关于使用通配符泛型转换对象的概念问题
Conceptual question about casting objects using wildcard generics
我试图理解为什么编译器对待内联声明的对象(使用通配符泛型)与首先将对象设置为变量的方式不同。
参见以下示例:
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()
returns 和 Class<?>
,所以我看不出应该以不同方式处理的原因。
因为 Class<A>
没有扩展 B
,你的最后两个陈述显然是错误的,这可以在编译时确定。另一方面,b1
是 Class<?>
类型,因此在编译时不知道 ?
是否扩展 B。需要进行运行时检查。
我试图理解为什么编译器对待内联声明的对象(使用通配符泛型)与首先将对象设置为变量的方式不同。
参见以下示例:
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()
returns 和 Class<?>
,所以我看不出应该以不同方式处理的原因。
因为 Class<A>
没有扩展 B
,你的最后两个陈述显然是错误的,这可以在编译时确定。另一方面,b1
是 Class<?>
类型,因此在编译时不知道 ?
是否扩展 B。需要进行运行时检查。