明确的铸造和重新分配

时间:2017-02-16 22:49:44

标签: java inheritance casting object-oriented-analysis

请考虑以下代码:

class A{}

class B extends A{

public static void main(String args[]){
   A exampleA = new A();
   B exampleB = new B();
   exampleB = exampleA;  // compile error}

我理解为什么会导致错误,因为您需要显式转换。但是,我不明白为什么我用以下代码得到编译错误:

class A{}

class B extends A{

public static void main(String args[]){
   A exampleA = new A();
   B exampleB = new B();
   exampleA = exampleB;
   exampleB = exampleA;  // compile error

从我的观点来看,指针exampleA现在指向与exampleB相同的对象,它是B类的对象。而且,由于重新指定了指针exampleA,我将最后一行代码解释为与exampleB相等= exampleB;编译器不同意,我没有想到编译器。有人能告诉我为什么会收到错误吗?

我还为两个类使用了getClass方法,输出显示两者确实指向同一个对象。因此,我很困惑。

我是编程新手,想了解编译器的思考方式。除了回答这个问题之外,任何书籍或其他来源的提示都可以帮助您区分编译器和运行时逻辑!

请注意,我知道如何解决第二个代码块,这只是通过显式转换。

3 个答案:

答案 0 :(得分:1)

编译器无法自动检测到这种情况。如果你明确地向下转换它应该工作。然后你负责确保右侧物体可以安全地向下投射。

通过exampleB = (B) exampleA;投降。

如果您执行此操作并且无法进行转发,则会在运行时获得异常。

此外,没有"指针"在Java中。参考文献类似但不相同。

答案 1 :(得分:0)

你似乎想知道编译器,所以我会尽可能多地把它放在这里。 java中的java编译器比一些人相信的更加信任。这是一个很好的例子,因为java允许你构造人工铸造机制,尽管在大多数情况下很难。因此,编译器在这里退后一步,相信你知道自己在做什么。显然,运行时间是以最奇妙的方式出现问题的地方,它在行动中看到不,那个演员阵容是不可能的。 在这个特定情况下,A类显然不能向下转换成B类的例子。但是,切换最后两行,我相信你会发现没有错误发生。这是因为B类肯定可以成为A类的一个例子,当你将eB设置为A类的一个例子,并将eA设置为B时,你会发现它们最终都是A类的例子。

class A{}

class B extends A{}

public static void main(String args[]){
    A exampleA = new A();
    B exampleB = new B();
    exampleB = exampleA;
    exampleA = exampleB;  // compile error should be fixed
}

编辑: 我意识到自己错了。有关详细信息,请参阅以下评论这是我的更正版本。

public static void main(String[] args) {
    A eA = new A();
    B eB = new B();
    A newAfromB = eB;
    eA = newAfromB;
}

答案 2 :(得分:-2)

你对物体的看法 - 它们的类型相同。

但是!指针仍然有不同的类型。

所以,这就是为什么会出现这个错误。