Java继承示例中的参考

时间:2015-02-03 01:05:59

标签: java inheritance super

public class Test1 {

    int a;
    int b;

}

public class Test2 extends Test1 {

    public int c;

    Test2(int a,int b,int c){

        this.a=a;
        this.b=b;      
        this.c=c;}
}


public class Driver {

    public static void main(String[] args) {

        Test2 test1 = new Test2(3,4,5);
        Test1 test = new Test1();

        test=test1;  //This line is true
        test1=test;  //This line is false

    }

}

即使我看了书中的例子,我也听不懂。怎么可能?为什么在“test1 = test”行遇到编译错误?有人可以解释一下吗?

1 个答案:

答案 0 :(得分:2)

赋值转换的规则(在将表达式的值赋给变量时会发生这种情况)在section 5.2 of the Java Language Specification中详细说明。特别是,将引用类型分配给更宽的引用变量始终是合法的:

  

如果 S S 的子类型(§4.10) Ť

在您的情况下,由于test的引用类型为Test1,因此分配Test1 类型的任何内容或Test1的任何子类型都是合法的test。但是,由于test1的类型为Test2,因此为Test1指定类型Test1的表达式是不合法的,因为Test2不是test的子类型。特别是,表达式Test1的类型为Test1,而Test2不是test的子类型。

请注意,这是一个编译时检查,它与test1 = (Test2) test; 在运行时可能具有的实际值的类型无关。如果您确定表达式实际上是较窄的类型,则可以使用强制转换:

ClassCastException

但是,如果test的实际值不是Test2类型(或其子类型),则会在运行时引发instanceof。因此,在进行此类转换时,您将失去编译时类型检查的一些好处。通常使用int x = 1; byte y = 2; x = y; // okay y = x; // ERROR -- requires a cast to narrow the type y = (byte) x; // okay 运算符来检查强制转换是否成功。但是,如果你发现自己编程是这样的,那就是“代码味道”:表明你的代码设计可能在某些方面存在缺陷。

原始值也会发生类似的事情:

ClassCastException

与引用类型不同,基本类型的强制转换永远不会抛出{{1}}。