您的第一个示例不会更改调用者中的变量someThing。该分配仅在 doSomething 方法中可见。
第二个样本确实改变了调用者中的someThing。
所以如果你想在调用者中更改someThing,选项2是可行的,而选项1是不可行的。
请参阅 Is Java "pass-by-reference" or "pass-by-value"? 了解为什么会这样。
假设以下代码,以及一个具有打印方法和字符串成员的Thing。
void foo() {
Thing one = new Thing("hello"); // 1
bar(one);
one.print(); // 5
}
void bar(Thing two) { // 2
two = new Thing("bye"); // 3
} // 4
1 处的赋值首先创建了一个新的 Thing 对象:
Thing{data="hello"}
然后在one中存储一个引用:
one *----- refs --------v
Thing{data="hello"}
当您在点 2 处输入 bar 时,会创建对同一对象的新引用:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------^
然后3 行与1 行做同样的事情,即创建一个新的Thing 对象:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------^
Thing{data="bye"}
然后将对该新对象的引用存储在two:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------v
Thing{data="bye"}
请注意,仅修改了 two。该分配更改了two 所指的内容。
当您从bar 返回时,在4 行,two 超出范围,“再见”事物不再有任何引用它(最终将被垃圾回收)。
one *----- refs --------v
Thing{data="hello"}
Thing{data="bye"} // dead, will be collected
所以在5 点,如您所见,hello 将被打印 - 没有任何改变 one 所指的对象。