[英]Why does the following code give a classcast exception?
Given below piece of code: 给出下面的代码:
//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
operator gives true so B
is a object of class A
. instanceof
运算符的值为true,因此B
是类A
的对象。 A
to B
its gives ClassCastException
even though B
is an sub-type of A
? A
强制转换为B
ClassCastException
给出ClassCastException
即使B
是A
的子类型呢? new A();
is simply not B
. 根本不是
B
It's the same as you were saying that "Every Animal is a Cat with no exceptions". 就像您说的“每个动物都是猫,没有例外”一样。 Which is not true.
这是不对的。
However, casting B
to A
would be correct (because every Cat is an Animal, with no exceptions): 但是,将
B
强制转换为A
是正确的(因为每个猫都是动物,没有例外):
A a = (A) new B();
A a = new B(); // is fine as B inherits A
B b = new A(); // is NOT fine as A does not inherit any thing from B
B is an instance of A that is right. B是正确的A的实例。 But A is not an instance of B. That's why you get the exception.
但是A不是B的实例。这就是为什么您会得到例外。
B b = (B) new A();
is the wrong statement cause A
doesn't inherits B
; 是错误的陈述,因为
A
不继承B
; rather B
inherits A
而是
B
继承了A
Allowing such casting would not be safe for few reasons. 出于种种原因,允许进行此类铸造并不安全。
1) Lets say that you added in your B
additional method of field which A
doesn't have like 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;
}
}
Now lets assume that this casting will work 现在让我们假设这种转换将起作用
B b = (B) new A();
So b
will hold instance of A
. 因此
b
将持有A
实例。 But later we can try invoking setX
from B
reference 但是稍后我们可以尝试从
B
参考调用setX
b.setX(1);
which should be fine because there was no casting exception so object from B
reference should be able to support this call. 这应该没问题,因为没有强制转换异常,因此
B
引用中的对象应该能够支持此调用。
What do you think, how should JVM react on this next line? 您如何看待,JVM应该如何对下一行做出反应? Should such code be allowed?
应该允许这样的代码吗?
No, base A
doesn't know how which code should be executed for setX
and even if it knew it, it doesn't have int x
field to store its data. 不,基
A
不知道应该如何为setX
执行哪个代码,即使知道,它也没有int x
字段来存储其数据。 So to prevent such situations JVM throws ClassCastException. 因此,为防止此类情况,JVM抛出ClassCastException。
2) You can say that: " OK, but my B
doesn't change interface, it doesn't add anything new to A
". 2)您可以说:“ 好,但是我的
B
不会更改接口,它不会为A
添加任何新内容 ”。 You are right, but allowing casting in this case is also dangerous, because while invoked methods from B
you should be able to expect that they will behave in a way described in B
class, or its subclasses. 没错,但是在这种情况下允许强制转换也是危险的,因为从
B
调用方法时,您应该可以期望它们将以B
类或其子类中描述的方式运行。
Lets say that we are building racing game and we have classes 可以说我们正在开发赛车游戏,并且有课程
class Car{
int getMaxSpeed(){
200;
}
}
class LimitedSpeedCar extends Car{
int getMaxSpeed(){
return 30;
}
}
Now you want to create racing track only for cars with limited speed. 现在,您只想为速度有限的汽车创建赛道。 So you are creating
LimitedSpeedCar[]
array to store only cars with limited speed. 因此,您要创建
LimitedSpeedCar[]
数组,以仅存储速度受限的汽车。 But guess what, because 但是你猜怎么着,因为
B b = (B) new A();
works fine it means that 正常工作意味着
LimitedSpeedCar lsc = (LimitedSpeedCar) new Car();
will also work so we can add to our race car without limits which is not what we wanted. 也将起作用,因此我们可以不受限制地添加到赛车中,这不是我们想要的。
B
is a subclass of A
, you cannot cast A
to B
. B
是A
的子类,不能将A
强制转换为B
In fact, maybe the concrete class of the new A
Object is another class than B
(let say a class C
that extends A
). 实际上,也许新
A
Object的具体类是B
以外的另一个类(比方说,扩展A
的类C
)。 So you cannot affirm that A
is an instance of B
. 因此,您不能肯定
A
是B
的实例。
An object of type B can be cast to variable of type A but not the other way around. 可以将类型B的对象强制转换为类型A的变量,但不能强制转换为其他类型。 B extends A so it could potentially have more functionality.
B扩展了A,因此它可能具有更多功能。 This might be a good time to go back and read up on polymorphism.
这可能是回头阅读多态性的好时机。
You can't down cast an object. 您不能向下投射对象。 You can create a
您可以创建一个
A a1 = new B()
. A a1 = new B()
。
But you can't create a 但是您不能创建一个
B b1 = new A()
It's simple like every German Shepard is a Dog. 就像每个德国谢泼德都是狗一样,这很简单。 So you can create a new German Shepard dog.
因此,您可以创建一条新的德国Shepard狗。
But you can't be sure that every Dog is a German Shepard. 但是您不能确定每只狗都是德国谢泼德犬。 Hence creating a new German Shepard of type dog is not supported.
因此,不支持创建新的dog类型的德国Shepard。 Read This
阅读此
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.