我实现了以下代码:
class A {
//some code
}
class B extends A {
// some code
}
class C {
public static void main(String []args)
{
B b1 = (B) new A();
A a1 = (B) new A();
}
}
当单独编译时,这两行都可以正常编译,但是使用给出运行时错误 java.lang.ClassException: A cannot be cast into 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 code
}
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
。
MainActivity.java 对不起,我的英语很差。
我一直收到JAXB转换错误。 在这一点上我不确定该纠正什么。 解组: 错误消息: 不能将条目强制转换为javax.xml.bind.JaxbElement 问题更新 @XmlAccessorType(XmlAccessStype.Field)公共类条目{ XML:
问题内容: 所以这工作: 但这不是: 总而言之,我得到了第一部分(拳击),但是我发现第二部分不起作用是非常不直观的。是否有特定的原因(除了String从Object继承而int不从Object继承)? 编辑: 为了完善我的问题,这也可以: 但是,以下内容却没有: 令人惊讶的是,您遇到了与String相同的问题: 在最后一行产生类强制转换异常。仍然有效: 问题答案: 我刚刚找到了我正在寻找自己的答案
问题内容: 我有。我想使用获得最大结果。这是我的代码: 这是我的: 现在我得到了。怎么了? 问题答案: 您的错误可能在以下行中: 其中query.list()返回BigInteger列表而不是Long列表。尝试将其更改为。
我不是一个设计师,但当我得到这个项目,我不能打开特别的一些屏幕,我认为他们是屏幕,我们只重用一些布局已经创建。不管怎么说谁能帮帮我吗?@override public void onBindViewHolder(@nonnull final ProductsAdapter.ViewHolder holder,final int position){String imageUrl=ProductsL