示例:
interface S {}
interface SS extends S {}
abstract class A<T extends S> {
T get() {…}
}
abstract class B<BT extends SS> extends A<BT> {}
为什么((B)someInstanceOfB).get()
返回类型为S
的对象(我们应该手动将其强制转换为SS
),此时编译器可以确定返回的对象至少是SS
类型1}}?
为什么编译器不使隐式类转换具有更清晰的代码?代码版本为1.5+,这对编译器来说并不是秘密。 (解决)
更新:为什么编译器不能编译B
类,因为它隐式具有方法BT get() { return super.get(); }
?
Java 1.7 +中是否解决了这个问题?
答案 0 :(得分:4)
通过转换为B
,您正在使用a raw type。
使用原始类型会从对象中删除所有通用信息,无论它在何处。
这意味着,对于原始类型B
,get
方法看起来像,它返回S
(因为这是擦除(即实际类型)在运行时使用的类型参数T
)。
为避免这种情况,绝不使用原始类型!它们专门用于向后兼容和与遗留代码的交互。
转而转向B<? extends SS>
。
不,这个问题可能永远不会在任何未来版本的Java中“解决”,因为当你正确使用泛型时它不存在。
关于更新:否,B
不的方法BT get()
。它有一个方法T get()
,其中T
绑定到类型参数BT
,它具有下限SS
。但是,由于在使用原始类型时会丢弃所有泛型类型信息,T
将仍然回退到原始擦除,即S
。
规则非常简单,基本上说“当你使用原始类型时,它就好像该类没有任何泛型”。然而,这种影响并不总是显而易见的,就像在这种情况下一样。
答案 1 :(得分:1)
您没有参数化B
的实例。
假设您有C
个实施SS
的课程:
然后,new B<C>().get();
将返回C
类型的对象。
在new B().get();
行上,您的IDE必须告诉您“B是原始类型。应该参数化通用类型B的参考。”。