我试图理解为什么编译器对待内联声明的对象(使用通配符泛型(与首先设置为变量的对象不同。
参见以下示例:
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。需要进行运行时检查。