首页 > 解决方案 > Generics Array Casting contradiction

问题描述

I'm facing a contradiction in how generics subtyping works. From my understanding, generics are nonvariant, so there should not be any subtyping relationship between the two.

Box<?> n =  new Box<>(null); 
Box<Object> error = (Box<T>) n; //error

Fails.

I understand that n of compile time type Box<?> can be type-casted to Box<T> as a subtyping relationship of Box<T> <: Box<?> exists. However since generics are invariant, i cannot assign a compile time type of Box<T> to Box<Object>.

With that in mind here comes the contradiction:

Box<T> g = new Box<>(t);
Box<Integer> fine = (Box<Integer>) g; //ok, but why?

It is strange because in the first example, we have shown that we cannot assign different generics together due to it being invariant. But in the 2nd example, I am able to do a type casting of compile type Box<T> to Box<Integer> .

though the 1 is an assignment and 1 is a typecasting operation, i would assume they work the same way. Is there a good explanation for this ?

Thanks in advance.

标签: javagenericscastingvariable-assignment

解决方案


需要明确的是,这在很大程度上是分配的问题,而不是演员表。

在您的第一个片段中

Box<?> n =  new Box<>(null); 
Box<Object> error = (Box<T>) n; //error 

错误应该类似于

类型不匹配:无法转换Box<T>Box<Object>

正如您所说,这试图告诉您 aBox<T>不是 的子类型Box<Object>,因此不能将赋值运算符右侧的表达式分配给error。这基本上与中描述的问题相同

在你的第二个片段

Box<T> g = new Box<>(t);
Box<Integer> fine = (Box<Integer>) g; //ok, but why?

在分配方面,编译器没有发现任何错误。您将 type 的表达式分配给 typeBox<Integer>的变量Box<Integer>

虽然 1 是一个赋值,而 1 是一个类型转换操作,但我会假设它们的工作方式相同。对此有很好的解释吗?

是的。Java语言规范声明

转换上下文允许转换表达式(第 15.16 节)的操作数转换为由转换运算符显式命名的类型。 与赋值上下文和调用上下文相比,强制转换上下文允许使用 §5.1 中定义的更多转换,并允许这些转换的更多组合。

JLS 继续解释允许哪些转换(另请参见5.1.6缩小引用转换,4.10子类型化),但短处是我们有一个未检查的缩小引用转换,这在赋值上下文中是不允许的。您可能还看到了编译器的警告

如果未检查缩小引用转换,则 Java 虚拟机将无法完全验证其类型正确性,可能导致堆污染(第 4.12.2 节)。为了向程序员标记这一点,未经检查的缩小引用转换会导致编译时未经检查的警告,除非被 @SuppressWarnings(§9.6.4.5) 抑制。

这就是为什么你会看到这些行为。你可以在你的第一个片段中引入一个额外的演员来使它编译

Box<?> n = new Box<>();
Box<Object> error = (Box<Object>)(Box<T>) n; // error

这更能代表您在第二个片段中所做的事情(您会收到类似的警告)。


推荐阅读