在哪里放置尝试在下面的程序中捕获来处理类转换异常?
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");
}