Java值传递疑问:Integer不可变导致修改未生效问题
为什么Integer作为参数传递后原值没变化?
这问题我当初刚学Java的时候也懵过!咱们一步步拆解你遇到的现象:
首先先看你的测试代码:
public class Test { public static void main(String[] args) { Test test = new Test(); Integer integer = 4; System.out.println(integer); test.change(integer); System.out.println(integer); } public void change(Integer integer) { integer++; } }
你预期输出4 5,但实际是4 4,核心原因要结合两个点来看:Java的值传递机制和Integer的不可变性。
1. Java的参数传递:全都是值传递
很多人会混淆引用类型的传递,但Java里不管是基本类型还是引用类型,都是值传递:
- 对于基本类型(比如int),传递的是变量值的副本;
- 对于引用类型(比如Integer),传递的是对象引用的副本——也就是说,
change方法里的integer参数,是main方法中integer变量的一个拷贝,它们一开始指向同一个Integer对象(值为4的那个)。
但这里的关键是:这个拷贝的引用,和原引用是相互独立的——如果在change方法里让这个拷贝指向新的对象,原引用不会受到任何影响。
2. Integer的不可变性:根本没法修改原对象
Integer类是**不可变(Immutable)**类,它的底层设计决定了一旦创建,对象的值就不能被修改:
- Integer内部存储值的字段是
private final int value,final修饰意味着这个字段一旦赋值就不能再改变; - 当你执行
integer++时,实际发生的是这几步:- 把Integer对象拆箱成int类型的数值(4);
- 数值加1,变成5;
- 把5重新装箱成一个新的Integer对象;
- 让
change方法里的那个拷贝引用,指向这个新的Integer对象。
这时候,main方法里的原integer变量,依然指向最初那个值为4的Integer对象,所以第二次打印还是4。
举个反例理解可变类的情况
如果咱们用一个自定义的可变类,比如:
class MutableInteger { int value; public MutableInteger(int value) { this.value = value; } } public class Test { public static void main(String[] args) { Test test = new Test(); MutableInteger mi = new MutableInteger(4); System.out.println(mi.value); test.change(mi); System.out.println(mi.value); } public void change(MutableInteger mi) { mi.value++; } }
这时候输出就是4 5——因为MutableInteger是可变的,我们修改的是同一个对象里的value字段,而不是创建新对象,所以原引用指向的对象值被改变了。
总结一下:你的代码里,不是值传递机制出了问题,而是Integer的不可变性导致integer++并没有修改原对象,而是创建了新对象,而这个新对象只在change方法的局部作用域里被引用,和main方法里的原变量没关系。
内容的提问来源于stack exchange,提问作者steve1337
相关产品推荐
相关产品推荐

