第 6 行的变量 t2 不是对该对象的唯一引用。有一个从 t 到对象 t2 的引用,它是在函数 go 中创建的,而对象 t2 又持有对 t1 的引用,它与函数 go 返回的对象相同。所以第 6 行只是减少了引用的数量,但仍然有对对象的实时引用。
编辑:让我们尝试更详细的解释,首先我修改了代码以使解释更容易。每行一个语句,变量名称不那么容易混淆 + 我用字母 A、B 和 C 标识了三个相关对象。
1. public class Tahiti {
2. Tahiti u;
3. public static void main(String[] args) {
4. Tahiti t = new Tahiti(); // object A
5. Tahiti t2 = t.go(t);
6. t2 = null;
7. // more code here
8. }
9. Tahiti go(Tahiti s) {
10. Tahiti s1 = new Tahiti(); // object B
11. Tahiti s2 = new Tahiti(); // object C
12. s1.u = s2;
13. s2.u = s1;
14. s.u = s2;
15. return s1;
16. }
17. }
在第 4 行:变量 t 被初始化以引用一个新对象。让我们称该对象本身为 A(它通常在 java 中没有名称,但为了便于解释,如果有名称会更容易)。
在第 5 行:t 被传递给函数 go 所以我们转到第 9 行
第 9 行:参数 s 引用了在第 4 行创建的对象 A
第 10 行:初始化变量 s1 以指向对象 B
第 11 行:初始化变量 s2 以引用对象 C
第 12 行:s1.u 设置为引用 s2,这意味着对象 B 获得对 C 的引用
第 13 行:s2.u 设置为引用 s1,因此对象 C 获取对 B 的引用
第 14 行:su 设置为引用 s2,这意味着对象 A 获取对 C 的引用注意 C 也有对 B 的引用,因此此时存在从 A 到 B 的链
第 15 行返回对象 B 并返回第 5 行
第 5 行:t2 设置为引用对象 B(B 现在被 t2 直接引用两次,一次是因为 t 引用对象 A,而对象 A 引用 C,而 C 引用 B)
第 6 行:引用 t2 设置为 null,因此 B 丢失了一个引用,但 t 仍然存在,指向 A 指 C 指 B