参考资料和选角

References and Casting

我正在努力理解我认为 Java 中的一个基本问题。 下面给出的答案是第 3 行倾向于 class 转换异常。我可以看到最初 a1 指向对象 A 的数组。但是在第 1 行上,a 没有设置为指向对象 b 的数组吗?因此,如果 a1 指向 a,它现在不应该也指向 b 吗?

Enthuware 的解释:-

当 运行 时,程序将在标记为 3 的行抛出一个 java.lang.ClassCastException。

行 //1 将在编译期间被允许,因为赋值是从 subclass 引用到 superclass 引用完成的。 //2 行中的转换是必需的,因为 superclass 引用被分配给 subclass 引用变量。这在 运行 时间有效,因为 a 引用的对象实际上是 B 的数组。 现在,第 //3 行的转换告诉编译器不用担心,我是一个优秀的程序员,我知道我在做什么,超级 class 引用 (a1) 引用的对象实际上是class B 在 运行 时间。所以没有编译时错误。但是在 运行 时,这失败了,因为实际对象不是 B 的数组而是 A 的数组。

public static void main(String args[]) {

    A[] a, a1;
    B[] b;
    a = new A[10];
    a1 = a;
    b = new B[20];
    a = b;         //line 1
    b = (B[]) a;   //line 2
    b = (B[]) a1;  //line 3

    }

}

class A {
}

class B extends A {}

And therefore if a1 was pointing to a should it now not also point to b?

没有

变量保存值并且完全独立于其他变量。如果您更改一个变量的值,您只会影响该变量。

如果有多个变量引用同一个对象,可以使用任何引用来更改对象,但引用的更改只会影响该引用。

在您的示例中,a 和 a1 引用了同一个数组。如果修改引用的对象,A的数组,使用a或a1是一样的,因为它们引用的是同一个对象。

A[] a, a1;
a = new A[10];
a1 = a;
/* You can use a or a1 to modify the object with the same results. */
a[0] = new A(); /* Equivalent to a1[0] = new A() */

如果您修改变量以引用另一个对象,另一个引用将保持不变。

A[] a, a1;
a = new A[10];
a1 = a;
a = new A[15]; /* a1 still references the first array and a the new one */

将对象引用用作函数参数时会发生类似的情况。

举个例子,给出比方法:

public static void uselessMethod(A[] a) {
    /* a is a local variable that makes reference to the object,
       modify the reference only has effect inside this method,
       but modify the array has effects outside the method */
    a = null;
}

如果你调用上面的方法,你的引用不会改变:

A[] a = new A[10];
uselessMethod(a);
System.out.println(a.length); /* This will print 10 */