如何使用开关大小写处理类转换异常



在哪里放置尝试在下面的程序中捕获来处理类转换异常?

Class Animal { }
Class Dog extends Animal { }
Class Cat extends Animal { }
Class MainRunner {
    public static void main(String args[]) {
        System.out.println("Main method started");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the key value");
        int key = sc.nextInt();
        Animal a = null;
        switch (key) {
            case 1 : a = new Cat(); break;
            case 2 : a = new Dog(); break;
            default : System.out.println("invalid choice");
            return;
        }
        Dog d = (Dog)a;
        System.out.println("main method ended");
    }
}

对于 Cat 类没有进行向下转换,因此当输入键值为 1 时,它将抛出类转换异常。如何使用尝试捕获来处理它?在哪里插入尝试捕获以便处理它?

是的,

如@Pshemo所述;您应该使用 instanceof 运算符来检查其 Dog 实例是否并相应地初始化它

Dog d=null;
if(a instanceof Dog)
  d=(Dog)a;
System.out.println(d);

理想情况下,您不需要向下投射。 除非必须调用子类实现的专用方法。否则,应使用接口/父类方法。

example : a.eat() // eat will be present in animal and will be implemented differently in each sub-class dog and cat.

但是,如果你需要吠叫;那么你可能需要子转换,但使用实例以安全的方式进行

if (a instanceof Dog) ((Dog)a).bark();
else syso("Animal cannot bark");

声明每种类型的两个变体并在 case 语句中初始化。

public class MainRunner {
        public static void main(String args[]) {
            System.out.println("Main method started");
            Scanner sc = new Scanner(System.in);
            System.out.println("Enter the key value");
            int key = sc.nextInt();
            Animal a = null;
            Dog d=null;
            Cat c=null;
            switch (key) {
                case 1 : a = new Cat();
                c=(Cat)a;
                break;
                case 2 : a = new Dog();
                d=(Dog)a;
                break;
                default : System.out.println("invalid choice");
                return;
            }
             if(d!=null){/*  to do */}
             if(c!=null){/*  to do */}
            System.out.println("main method ended");
        }

不需要任何尝试捕获。 您可以通过仅使用如下所示instanceof运算符来避免ClassCastException -

Class Animal { }
Class Dog extends Animal { }
Class Cat extends Animal { }
Class MainRunner {
    public static void main(String args[]) {
        System.out.println("Main method started");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the key value");
        int key = sc.nextInt();
        Animal a = null;
        switch (key) {
        case 1 : a = new Cat(); break;
        case 2 : a = new Dog(); break;
        default : System.out.println("invalid choice");
        return;
        }
        /* 
         * as per your logic of default block, for invalid choice control is getting 
         * returned back from default block only and if control comes here it means 
         * `a` will not have null value, so skipping null check
         * */
        if(a instanceof Dog){
            Dog d = (Dog)a;
            }
        else{
            Cat c = (Cat)a;
            }
        System.out.println("main method ended");
        }
    }

这里的人们正在为您提供解决方案(或者我最好称他们为"黑客"(来解决您的这个问题,而解决方案是完全避免这种情况。

拥有Animal类的全部意义在于避免以后降级。你的开关基本上是工厂模式(结帐步骤3(所做的事情,这种模式广泛用于库和框架,而不仅仅是在Java中。你不知道工厂里有什么结果,这实际上是一件好事,它给了你和交付实际实现的人(不一定是你(很大的灵活性。

如果你想,比方说,向下投射到Dog,因为你需要调用bark方法 - 不要,Animal类中创建makeSound方法,然后在Dog类中相应地覆盖/实现它。

无需捕获异常,只需在强制转换之前使用instanceof方法即可。

public static void main(String args[]){
        System.out.println("Main method started");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the key value");
        int key = sc.nextInt();
        Animal a = null;
        switch (key){
            case 1 : a = new Cat(); break;
            case 2 : a = new Dog(); break;
            default : System.out.println("invalid choice");
            return;
        }
        Dog d;
        Cat c;
        if(a!= null && a instanceof Dog)
            d =(Dog)a;
        else if(a!= null && a instanceof Cat)
            c = (Cat)c;
        System.out.println("main method ended");
    }

最新更新