在构造函数中混淆Java分配引用

时间:2014-10-23 18:21:39

标签: java jvm

有人可以解释为什么第二个输出不为空?我知道因为参考价值而存在999。

public class Set {

    int e[] = null;

    public Set(int[] e ) {
        this.e = e;
    }

    public void printSet() {
        for(int i = 0 ; i < e.length; i++) {
            System.out.println(e[i]);
        }
    }


    public static void main(String[] args) {
        int[] v = {1,2,3,4,5};

        Set m = new Set(v);
        m.printSet();

        v[0] = 999;
        v = null;

        System.out.println("-----------------");

        m.printSet();


    }

}

输出

1
2
3
4
5
-----------------
999
2
3
4
5

3 个答案:

答案 0 :(得分:1)

由于e仍然具有对数组的引用,因此使v引用无效不会使数组无法访问。

public Set(int[] e) {
    this.e = e; // <-- reference to the array
}

v[0] = 999;
v = null; // <-- now v doesn't refer to the array, but e still does.

答案 1 :(得分:1)

main()中的第一行:     int [] v = {1,2,3,4,5}; 这就是创建两个实体:

  • 一个是包含数字1到5的整数数组
  • 第二个是名为v的引用,它当前指向后面提到的数组

您将v传递给Set类构造函数:

Set m = new Set(v);

通过执行此操作,您将数组的位置传递给构造函数,构造函数创建了对同一数组对象的第二个引用,并将其称为e。

然后你取消了v引用

v = null;

通过这样做,您告诉Java v不应再指向先前创建的整数数组对象。然而,这本身并不意味着整数数组将会灭亡。它仍然由Set.e引用引用。当该引用无效时,该数组将成为符合垃圾收集条件,并且在某些时候将从内存中删除。

答案 2 :(得分:0)

v[0] = 999;

你只是改变了一个由你的局部变量和类实例引用的对象。

v = null;

你刚才让局部变量引用了一个新实例(或缺少它) 碰巧引用前一个值的类实例字段不受影响。