[英]Why does the Eclipse Java compiler complain about an unchecked cast for inner derived types?
请考虑以下具有非静态内部类的泛型类Base<ID>
。
public class Base<ID> {
ID id;
public Base(ID id) {
this.id = id;
}
public ID getId() {
return id;
}
protected class BaseInner {
String text = "Inner";
}
protected void method(BaseInner o) {
o.text = "Foo";
}
}
该方法Base.method
采用类型的参数BaseInner
。 现在考虑以下派生类。
public class Sub<ID> extends Base<ID> {
public Sub(ID id) {
super(id);
}
@Override
protected void method(BaseInner o) {
if (o instanceof Sub.SubInner) {
SubInner sub = (SubInner) o; // Why does this cast emit an "unchecked cast" warning
sub.text = "Bar";
sub.value = 1337;
}
}
protected class SubInner extends BaseInner {
Number value = 42;
}
}
Sub
类派生自Base
,内部类SubInner
派生自内部类BaseInner
。 Sub
的泛型类型参数ID
作为类型参数传递给基类Base
。
我的问题:为什么编译器SubInner
在Sub
的重写method
中抱怨从BaseInner
到SubInner
?
为了理解警告,我试图构建一个用例,其中使用Sub<B>.SubInner
调用Sub<A>
的method
来证明警告是正确的。 但是,如果类型不兼容,我能想到的任何内容(包括? extends
和? super
)会在方法调用上发出编译器错误。
所以我猜没有理由在method
中对未经检查的强制转换进行警告。 我错过了什么?
由于方法覆盖发生在Sub<ID>
实现中,编译器能够将SubInner
的泛型类型SubInner
为Sub<ID>.SubInner
。 所以质疑这不是重复!
Eclipse编译器警告是
类型安全:未经检查从Base <ID> .BaseInner转换为Sub <ID> .SubInner
如果我使用Base<ID>.BaseInner
作为方法参数,也不在演员表达式中使用Sub<ID>.SubInner
,那么Sub<ID>.SubInner
也不会改变。
这接缝是Eclipse编译器问题。
Oracle编译器( javac
)不会在此处省略任何警告。
在这种情况下,未经检查的强制转换意味着您正在从非限定类型转换为泛型类型。
Set<String> set = new HashSet();
此行也将生成未经检查的分配警告。
出现此警告是因为编译器无法在编译时删除强制转换是否安全。
SubInner实例具有对Sub实例的引用。 您正在从Base.BaseInner进行强制转换,因此您也从Base转换为Sub <ID>。 因此,您正在收到此警告。
编辑
解决方案是使用泛型参数。
public class Base<ID> {
ID id;
public Base(ID id) {
this.id = id;
}
public ID getId() {
return id;
}
protected class BaseInner {
String text = "Inner";
}
protected void method(Base<ID>.BaseInner o) {
o.text = "Foo";
}
}
public class Sub<ID> extends Base<ID> {
public Sub(ID id) {
super(id);
}
@Override
protected void method(Base<ID>.BaseInner o) {
SubInner sub = (SubInner) o;
sub.text = "Bar";
sub.value = 1337;
}
protected class SubInner extends BaseInner {
Number value = 42;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.