将基类对象转换为扩展基类的类时的ClassCastException

时间:2016-01-19 15:47:29

标签: java constructor

我在代码行中有 提到的评论,我想了解 ,如下所示:

  1. 我不明白这行代码: 的 Xyz obj3=(Xyz) obj1;

  2. Abc无法转换为Xyz类型。已编译,但在执行期间返回异常: Xyz obj2=(Xyz)new Abc();

    class Abc
    {
    
         Abc()
    
        {
    
        System.out.println(" Hello ");
    
        }
    
        void show()
        {
            System.out.println("Conco constructor w/ Super Class");
        }
    
    }
    
    class Xyz extends Abc
    
    {
    
        Xyz()
    
        {
            System.out.println(" Hi ");
        }
    
        void display()
        {
            System.out.println("ConsNew3 constructor w/ Extends Class Conco");
        }
    
        public static void main(String arg[])
        {
            Xyz obj=new Xyz();
    
            Abc obj1=new Xyz(); 
            obj1.show();
    
            Xyz obj3=(Xyz) obj1; // I didnt't  understand this line of code
    
    
            /*Xyz obj2=(Xyz)new Abc(); Abc cannot be cast to Xyz type . Compiled , but returns exception during execution */
    
    
        }
    }
    

2 个答案:

答案 0 :(得分:2)

一般来说,人类在抽象符号方面并不是很好,尽管程序需要这样。

编程中的初学者(更准确地说是任何人)不应该使用像Abc和Xyz这样的抽象名称,这甚至会让高级程序员感到困惑。

为什么不将Abc重命名为Animal,将Xyz重命名为Dog。

然后你有:

Dog obj3=(Dog) obj1; // works because Dog is an Animal.
Dog obj2=(Dog) new Animal(); // does not compile because not all Animals are Dogs

答案 1 :(得分:1)

Xyz obj3=(Xyz) obj1;此行有效,因为XyzAbc

Xyz obj2=(Xyz)new Abc();此行不起作用,因为并非所有Abc都是Xyz s

正如评论中提到的那样,以这种方式命名是更有意义的。

  

Abc == Animal

     

Xyz == Dog

Dog obj3 = (Dog) obj1;

obj1之前已被实例化为Dog,尽管它由更通用的Animal对象持有。它仍然是Dog的一个实例,因此可以将其强制转换为Dog

Dog obj2 = (Dog) new Animal();

Animal不一定是Dog s。

为了避免这样的问题,您可以使用instanceof运算符。这将测试通用对象是否是另一个实例,通常是更具体的对象。

您可以按如下方式使用它。

Object myGenericDog = new Dog();
Animal myAnimal = new Animal();

if(myGenericDog instanceof Animal){
    myAnimal = (Animal) myGenericDog;
}

为了将来参考,在实际代码和示例代码的情况下,对于编写代码的开发人员以及可能最终维护代码以使用描述性类名的任何未来开发人员来说,它更有益。注意:XyzAbc不是描述性。他们引入了不必要的复您可以通过选择名词和描述类的责任来改进自己的代码和示例。