为什么以下代码无法编译?
interface Iface<T> { }
class Impl<T> implements Iface<T> { }
class TestCase {
static Class<? extends Iface<?>> clazz = Impl.class;
}
错误是
java:不兼容的类型:
java.lang.Class<Impl>
无法转换为java.lang.Class<? extends Iface<?>>
但我不明白为什么不捕获通配符。
这里的子类型关系为:
Class<? extends Iface>
╱ ╲
Class<? extends Iface<?>> Class<Impl>
(我在回答“无法从转换List<List>
为List<List<?>>
”中解释了这一点。)
因此本质上它不会编译,因为它是横向转换。
如果可能的话,您可以执行我在那边描述的转换:
(Class<? extends Iface<?>>)(Class<? extends Impl>)Impl.class
如果您无法进行转换,则可能只需要处理raw bound即可Class<? extends Iface>
。主要由于警告而令人讨厌,但它打开了发生错误的可能性:
interface Iface<T> {
void accept(T a);
}
class Impl2 implements Iface<String> {
public void accept(String a) { }
}
class TestCase {
static Class<? extends Iface> clazz = Impl2.class;
public static void main(String[] args) throws Exception {
// throws ClassCastException
clazz.newInstance().accept(new Object());
}
}
不太可能发生,但是我想这取决于您在做什么。
我倾向于认为这是Java类型系统的问题。
可能应该有一个特殊的规则,即类型实参? extends T<?>
包含类型实参? extends T
,例如Class<? extends T>
将a转换为Class<? extends T<?>>
。从定义子类型(T
是的超类型T<?>
)的现有方式的角度来看,这没有任何意义,但从类型安全的角度来看,这是有意义的。
或者,例如List.class
应该是Class<List<?>>
而不是Class<List>
。
还是比我聪明的人可以想到的其他一些聪明的东西。
ClassCastException
我上面描述的有趣的事情是它是完全人为的。实际上,使用未经检查的演员表阻止它会引起警告。
我想这只是Java泛型尚未完成的一个信号。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句