参考和铸造

时间:2015-02-06 16:14:17

标签: java reference pass-by-reference pass-by-value

我很难理解我认为Java中的一个基本问题。 在答案下面,第3行倾向于类强制转换异常。我可以看到原来a1指向了一个对象A的数组。但是在第1行上并没有将get设置为指向对象b的数组?因此,如果a1指向a,它现在也不指向b?

来自Enthuware的解释: -

程序将在运行时在标记为3的行处抛出java.lang.ClassCastException。

编译期间将允许第1行,因为赋值是从子类引用到超类引用完成的。 需要在第//行中进行转换,因为超类引用被分配给子类引用变量。这在运行时工作,因为a引用的对象实际上是B的数组。 现在,//第3行的演员告诉编译器不要担心,我是一个优秀的程序员,我知道我在做什么,超类引用(a1)引用的对象实际上是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 {}

2 个答案:

答案 0 :(得分:1)

  

因此,如果a1指向a,它现在也不指向b?

没有

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

答案 1 :(得分:0)

如果有多个变量引用同一个对象,则可以使用任何引用完成对象的更改,但引用中的更改仅影响该引用。

在您的示例中,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 */