[英]java.lang.Class generics and wildcards
为什么以下代码无法编译?
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<?>>
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
如果你不能进行演员表演,那么你可能只需处理一个原始的有界Class<? extends Iface>
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<?>
包含一个类型参数? extends T
? extends T
使得例如一个Class<? extends T>
Class<? extends T>
转换为Class<? extends T<?>>
Class<? extends T<?>>
。 从定义子类型的现有方式( T
是T<?>
的超类型)的角度来看,这没有意义,但从类型安全的角度来看它是有意义的。
或者例如List.class
应该是Class<List<?>>
而不是Class<List>
。
或者其他一些比我更聪明的聪明人可以想到。
我上面描述的ClassCastException
的有趣之处在于它完全是人为的。 实际上,使用未经检查的强制转换防止它会导致警告。
我想,只是表明Java中的泛型尚未完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.