Java 为什么下面的代码会给出一个classcast异常?
下面给出一段代码:Java 为什么下面的代码会给出一个classcast异常?,java,inheritance,Java,Inheritance,下面给出一段代码: //Super class class A { void m1() { System.out.println("A"); } } //Extending the super class class B extends A { void m1() { System.out.println("B"); } } // Class with the main method public class C exte
//Super class
class A {
void m1() {
System.out.println("A");
}
}
//Extending the super class
class B extends A {
void m1() {
System.out.println("B");
}
}
// Class with the main method
public class C extends B {
void m1() {
System.out.println("C");
}
}
//in some main method
B b1 = new B(); //creating B object
System.out.println(b1 instanceof A); //gives true
B b = (B) new A();
b.m1();
instanceof运算符为true,因此B是类a的对象。
但为什么在将A转换为B时,即使B是A的子类型,它也会给出ClassCastException呢?
新A;根本不是B
这和你说的一样,每种动物都是猫,没有例外。但事实并非如此
但是,将B转换为A是正确的,因为每只猫都是动物,没有例外:
A a = (A) new B();
B是A的一个正确的例子。但是A不是B的一个实例。这就是为什么会出现异常。B B=B新的A;是错误的语句导致A不继承B;相反,B继承了A,允许这样的铸造是不安全的 1假设您在B中添加了A不喜欢的字段的附加方法
class A {
void m1() {
System.out.println("A");
}
}
class B extends A {
void m1() {
System.out.println("B");
}
private int x;
public void setX(int x) {
this.x = x;
}
}
现在,让我们假设这个铸造将工作
B b = (B) new A();
所以b将保存A的实例。但稍后我们可以尝试从b引用调用setX
b.setX(1);
这应该很好,因为并没有强制转换异常,所以B引用中的对象应该能够支持此调用。
您认为JVM在下一行应该如何反应?这样的代码应该被允许吗
不,base A不知道应该如何为setX执行哪些代码,即使它知道,它也没有int x字段来存储它的数据。所以为了防止这种情况,JVM抛出ClassCastException
2你可以这样说:好的,但我的B没有改变接口,它没有给A添加任何新的内容。你是对的,但在这种情况下允许强制转换也是危险的,因为当从B调用方法时,你应该能够期望它们会以B类或其子类中描述的方式运行
让我们说,我们正在建设赛车游戏,我们有课
class Car{
int getMaxSpeed(){
200;
}
}
class LimitedSpeedCar extends Car{
int getMaxSpeed(){
return 30;
}
}
现在,您希望仅为速度有限的车辆创建赛道。因此,您正在创建LimitedSpeedCar[]数组,以仅存储速度有限的车辆。但是你猜怎么着,因为
B b = (B) new A();
很好,这意味着
LimitedSpeedCar lsc = (LimitedSpeedCar) new Car();
也将起作用,因此我们可以无限制地添加到赛车中,这不是我们想要的。B是a的子类,不能将a转换为B。事实上,也许新A对象的具体类是另一个类,而不是一个扩展了A的C类。所以你不能肯定A是B的实例。B类型的对象可以转换为A类型的变量,但不能反过来。B扩展了A,因此它可能具有更多功能。这可能是一个回过头来阅读多态性的好时机。您不能向下投射对象。您可以创建一个 a1=新的B 但是你不能创建一个 B b1=新的A 这很简单,就像每个德国牧羊犬都是狗一样。所以你可以创造一个新的德国谢泼德狗 但你不能确定每只狗都是德国雪豹。因此,不支持创建新的德国狗型谢泼德犬。 阅读
LimitedSpeedCar lsc = (LimitedSpeedCar) new Car();