为何无法修改Java代码中num对象的值?如何修正实现该操作
为啥这段Java代码改不了num的值?怎么修复?
咱们先把核心问题点透:Java里的参数传递永远是「值传递」——哪怕是引用类型,传递的也是原引用的一个「副本」,不是引用本身。再加上Integer是个不可变类,这俩因素加起来,就导致你的代码根本碰不到原来的num对象。
先看你的代码为啥没用
当你调用test.change(test.num)的时候:
test.num是一个指向值为1的Integer对象的引用,Java会把这个引用复制一份,传给change方法里的参数n。- 在
change方法里把n = null,只是把这个副本引用设为null了,原来的test.num还是死死指着那个值为1的Integer对象,半毛钱影响都没有。 - 所以最后
print输出的还是原来的1。
几种修复方案
方案1:直接操作成员变量(最简单)
既然change是Test类的成员方法,直接在方法里操作this.num就行,根本不需要传参数:
public class Test { public Integer num = 1; public void change() { this.num = null; // 直接改成员变量 } public void print() { System.out.println(num); } public static void main(String[] args) { Test test = new Test(); test.change(); test.print(); // 输出null } }
方案2:用自定义的可变包装类
因为Integer是不可变的(一旦创建就改不了内部的值),如果必须通过参数传递来修改,可以自己写个可变的整数包装类:
// 自定义可变整数容器 class MutableInt { public int value; public MutableInt(int value) { this.value = value; } } public class Test { public MutableInt num = new MutableInt(1); public void change(MutableInt n) { n.value = 0; // 修改容器里的数值,而不是引用本身 // 如果要模拟"null"的效果,可以加个isNull标记,或者用Integer类型存value } public void print() { System.out.println(num.value); } public static void main(String[] args) { Test test = new Test(); test.change(test.num); test.print(); // 输出0 } }
方案3:返回新值并手动赋值
如果不想改方法的参数结构,可以让change方法返回你想要的新值,然后在main里给test.num赋值:
public class Test { public Integer num = 1; public Integer change(Integer n) { return null; // 返回你需要的新值 } public void print() { System.out.println(num); } public static void main(String[] args) { Test test = new Test(); test.num = test.change(test.num); // 接收返回值并赋值 test.print(); // 输出null } }
最后再划个重点
- 别再纠结Java有没有引用传递了,它真的只有值传递,引用类型传的是引用的副本
- 像
Integer、String这种不可变类,没法修改它们的内部状态,只能重新给引用赋值 - 如果要通过方法修改对象状态,要么直接操作成员变量,要么用可变的对象容器
内容的提问来源于stack exchange,提问作者Fergus
相关产品推荐
相关产品推荐

