关于使用通配符泛型强制转换对象的概念性问题



我试图理解为什么编译器对待内联声明的对象(使用通配符泛型(与首先设置为变量的对象不同。

参见以下示例:

public class SillyTest{
interface A<T extends B> {}
interface B {}
@Test
public void m() {
Class<?> b1 = A.class.getClass();
Class<? extends B> bb1 = (Class<? extends B>) b1; // works fine
Class<? extends B> bb2 = (Class<? extends B>) A.class.getClass(); // doesn't compile
Class<? extends B> bb3 = (Class<? extends B>)(A.class.getClass()); // also doesn't compile
}
}

注意:根据编译器配置,您可能需要添加@SuppressWarnings("unchecked")注释

为什么编译器处理这两种情况不同?我希望由于编译器内联,这些调用无论如何都应该是等效的。除了这是一个未检查的强制转换(可能工作,也可能不工作(之外,getClass()还返回一个Class<?>,所以我看不出有什么理由应该以不同的方式处理它。

由于Class<A>没有扩展B,所以最后两条语句显然是错误的,这可以在编译时确定。另一方面,b1属于Class<?>类型,因此在编译时不知道?是否扩展了B。需要进行运行时检查。

最新更新