【问题标题】:How can I handle the Class Cast Exception using switch case?如何使用 switch case 处理 Class Cast Exception?
【发布时间】:2018-04-08 07:55:04
【问题描述】:

在下面的程序中哪里可以放置try catch来处理Class Cast Exception?

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类没有向下转型,所以当输入key值为1时,会抛出Class cast Exception。如何使用 try catch 来处理它?在哪里插入 try catch 以便处理?

【问题讨论】:

  • 能否请您使用java代码美化器正确缩进代码?
  • 为什么要处理异常?通过使用instanceof 检查其类型,您可以阻止它。但是如果你必须使用try-catch,那么你能解释一下你在正常使用时遇到了什么问题吗(我们使用try to wrap section会抛出异常;catch提供处理方式)?

标签: java exception


【解决方案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.

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

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

【讨论】:

    【解决方案2】:

    声明每种类型的两个变量并在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");
            }
    

    【讨论】:

      【解决方案3】:

      不需要任何try catch。您可以通过使用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");
              }
          }
      

      【讨论】:

        【解决方案4】:

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

        拥有Animal 类的全部意义在于避免以后向下转换。你的 switch 基本上和Factory Pattern (checkout Step 3) 一样,这种模式被广泛用于库和框架中,而不仅仅是在 Java 中。事实上,您不知道工厂生产了什么,这实际上是一件好事,它为您和交付实际实现的人(不一定是您)提供了很大的灵活性。

        如果你愿意,比如说,向下转换为 Dog,因为你需要调用 bark 方法 - 不要,在 Animal 类中创建 makeSound 方法,然后在Dog 班级。

        【讨论】:

          【解决方案5】:

          不需要捕获异常,只需使用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");
              }
          

          【讨论】:

          • 虽然我同意instanceof,但以这种方式使用它对 OP 有何帮助?现在Dog d 的范围仅限于声明它的那一行。
          • @Pshemo 你是对的,我只是假设这是一个示例代码来显示instanceof 的用法,而不是真正的应用程序。稍微编辑了代码,但它仍然不是一个干净的代码:)
          猜你喜欢
          • 1970-01-01
          • 2015-11-05
          • 2021-11-01
          • 2013-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-03
          • 1970-01-01
          相关资源
          最近更新 更多