java.lang.ClassException:不能将A强制转换为B

java.lang.ClassException:不能将A强制转换为B,第1张

java.lang.ClassException:不能将A强制转换为B

type变量

A
可以
A
像在case类中那样存储对类型或其子类型的对象的引用
B

因此,可能会有类似以下的代码:

A a = new B();

变量

a
是类型的,
A
因此它只能访问该类的API,而不能访问在类B中添加的方法,即它所指向的对象。但是有时我们希望能够访问那些方法,因此应该可以以某种方式将引用存储
a
在更精确类型的某个变量中(在此
B
),通过该变量我们可以访问B类中的其他方法。
但是我们如何去做?

让我们尝试通过以下方式实现它:

B b = a;//WRONG!!! "Type mismatch" error

这样的代码会给出编译时

Type mismatch
错误。碰巧使我们免于这种情况:

  • class B1 extends A
  • class B2 extends A

而且我们有

A a = new B1();

现在让我们尝试分配

B1 b = a;
。请记住,
编译器不知道变量中实际包含的内容,
a
因此它需要生成对所有可能的值都安全的代码。如果编译器不会抱怨,
B1 b = a;
也应该允许编译
B2 b= a;
。因此,为了安全起见,我们不允许这样做。

所以,我们应该做些什么来分配基准从

a
B1
?我们需要 明确
告诉编译器,这里我们意识到潜在的类型不匹配问题,但是我们确保
a
可以安全地将持有的引用分配给type变量
B
。我们通过 值从
a
类型 转换
为类型
B
来实现
(B)a

    B b = (B)a;

但是让我们回到您的问题的例子

B b1 = (B) new A();A a1 = (B) new A();

new
运算符返回与创建对象相同类型的
new A()
引用,因此返回该类型的引用,
A
因此

B b1 = (B) new A();

可以看作是

A tmp = new A();B b1 = (B) tmp;

这里的问题是 您不能在其派生类型的变量中存储对超类对象的引用
为什么存在这种限制?可以说派生类添加了一些超类型不喜欢的新方法

class A {    // some pre}class B extends A {    private int i;    public void setI(int i){        this.i=i;    }}

如果允许的话

B b = (B)new A();

您以后可能会调用

b.setI(42);
。但这是正确的吗?否,因为类A的实例没有方法
setI
或该方法使用的 字段
i

所以要防止这种情况

(B)new A();
运行时 抛出
java.lang.ClassCastException



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5055394.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存