Java泛型类型问题 [英] Java generic type issue
问题描述
请考虑以下简化示例:
package com.test;
class B<S> {
B(Class<S> clazz) {}
}
class A<T> {
class SubB extends B<SubB> {
SubB() {
super(SubB.class);
}
}
}
尽管IntelliJ没有显示任何错误(通常在存在编译错误时会显示错误),但是启动程序时的实际编译以super(SubB.class);
中的错误结束:
Although IntelliJ is not showing any error (as it usually does when compile errors exist), the actual compilation when starting the program ends with error located in super(SubB.class);
:
错误:(8,23)java:不兼容的类型:
java.lang.Class<com.test.A.SubB>
无法转换为java.lang.Class<com.test.A<T>.SubB>
我很好奇,为什么会这样?那我该怎么解决呢?
I am curious, why is this happening? And how could I solve it?
使用AdoptOpenJDK 11进行编译.
Compilation is done with AdoptOpenJDK 11.
推荐答案
此行为的原因有些复杂.考虑java.util.List.class
,其类型为Class<java.util.List>
,而不是Class<java.util.List<?>>
.这是类文字的限制.
The reason for this behavior is a bit complicated. Consider java.util.List.class
, which has the type Class<java.util.List>
, not Class<java.util.List<?>>
. This is a limitation of the class literal.
在您的示例中,SubB.class
具有类型Class<com.test.A.SubB>
,同样具有SubB的原始类型.但是构造函数希望使用Class<com.test.A<T>.SubB>
类型.
In your example, SubB.class
has the type Class<com.test.A.SubB>
, again with the raw type of SubB. But the constructor expects some type of Class<com.test.A<T>.SubB>
.
这就是为什么我们需要将文字转换为所需的类型:
That's why we need to cast the literal to it's desired type:
super((Class<SubB>) (Class<?>) SubB.class);
这将产生警告,但是快速检查将发现没有什么可担心的.
This will produce a warning, but a quick examination will show that there is nothing to worry about.
这篇关于Java泛型类型问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!