您的第一个示例不会更改someThing
调用者中的变量。分配仅在doSomething
方法中可见。
第二个样本someThing
在调用者中确实发生了变化。
所以如果你想改变someThing
调用者,选项2是可行的,而选项1是不可行的。
请参阅Java 是“按引用传递”还是“按值传递”?为什么会这样。
假设下面的代码,并且 aThing
有一个 print 方法和一个 String 成员。
void foo() {
Thing one = new Thing("hello"); // 1
bar(one);
one.print(); // 5
}
void bar(Thing two) { // 2
two = new Thing("bye"); // 3
} // 4
point 处的赋值1
首先创建了一个新的 Thing 对象:
Thing{data="hello"}
然后将引用存储在one
:
one *----- refs --------v
Thing{data="hello"}
当您bar
在点输入时2
,会创建对同一对象的新引用:
one *----- refs --------v
Thing{data="hello"}
two *----- refs --------^
然后 line和 line3
做同样的事情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"}
注意 onlytwo
被修改。分配改变了two
所指的内容。
当您从bar
, at line返回时4
,two
超出范围,“再见”事物不再有任何引用它的东西(最终将被垃圾收集)。
one *----- refs --------v
Thing{data="hello"}
Thing{data="bye"} // dead, will be collected
因此5
,正如您所看到的,hello
将打印点 - 没有任何东西改变了所one
引用的对象。