为什么下面的代码没有编译?
interface Iface<T> { }
class Impl<T> implements Iface<T> { }
class TestCase {
static Class<? extends Iface<?>> clazz = Impl.class;
}错误是
java.lang.Class<Impl>:不兼容类型:无法将java.lang.Class<? extends Iface<?>>转换为java.lang.Class<? extends Iface<?>>
但我不明白为什么通配符没有捕捉到。
发布于 2015-05-07 04:32:58
这里的子类型关系是:
Class<? extends Iface>
╱ ╲
Class<? extends Iface<?>> Class<Impl>(我在对的答复中解释了这一点。)
所以本质上它不编译,因为它是一个横向的转换。
如果可能的话,你可以做我在那里描述的演员:
(Class<? extends Iface<?>>)(Class<? extends Impl>)Impl.class如果您不能进行强制转换,那么您可能只需要处理一个原始的有界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>将转换为Class<? extends T<?>>。从定义子类型的现有方式(T是T<?>的超级类型)的角度来看,这是没有意义的,但从类型安全性的角度来看,这是有意义的。List.class应该是Class<List<?>>而不是Class<List>。我上面描述的ClassCastException的有趣之处在于,它完全是人为的。事实上,使用未检查的强制转换来阻止它会引起警告。
我想,这只是一个迹象,表明Java中的泛型还没有完成。
发布于 2015-05-07 01:24:04
因为类型擦除,当你说Impl.class时,你会得到一个Class<Impl>。也就是说,你可以说
Class<Impl> clazz = Impl.class;泛型是编译时类型安全的特性.
https://stackoverflow.com/questions/30090242
复制相似问题