Java 泛型方法执行隐式转换,而非泛型方法需要显式转换
这个问题是相关的。可以通过添加强制转换来执行未经检查的转换来解决原始问题。现在我有了以下代码:Java 泛型方法执行隐式转换,而非泛型方法需要显式转换,java,generics,type-inference,unchecked-conversion,Java,Generics,Type Inference,Unchecked Conversion,这个问题是相关的。可以通过添加强制转换来执行未经检查的转换来解决原始问题。现在我有了以下代码: import java.util.EnumSet; class A { static enum E1 { X } private static <T extends Enum<T>> EnumSet<T> barEnum(Class<T> x) { return null; } pri
import java.util.EnumSet;
class A {
static enum E1 {
X
}
private static <T extends Enum<T>> EnumSet<T> barEnum(Class<T> x) {
return null;
}
private static void foo1(EnumSet<E1> s, E1 e) {
EnumSet<E1> x2 = barEnum((Class<E1>)e.getClass());
}
private static void foo2(EnumSet<E1> s) {
EnumSet<E1> x = barEnum((Class<E1>)s.iterator().next().getClass());
}
}
这显然包含未经检查的转换,并且编译时带有相应的警告。但是我没有将getClass()
的结果显式地转换到Class
中。由于foo1()
是泛型方法foo3()
的一个实例,我希望我也需要在这里添加强制转换。比较foo1()
和foo4()
private static void foo4(EnumSet<E1> s) {
EnumSet<E1> x = barEnum(s.iterator().next().getClass());
}
private静态void foo4(枚举集){
EnumSet x=barEnum(s.iterator().next().getClass());
}
…这两者实际上是相似的(主要区别在于
foo1()
中的e1e
参数)。但是foo1()
会编译,但是foo4()
不会编译。我觉得这是前后矛盾的。是否有允许泛型方法进行隐式转换的规则?我的建议是阅读优秀的Java泛型常见问题解答:
恕我直言,它不会编译,因为静态方法不会继承泛型类的类型参数。然后,您试图获取参数化类型的运行时类信息,这将不起作用,因为Java在其泛型实现中使用擦除
Java中的泛型并不容易,一旦您超越了简单的集合等。这就是为什么FAQ是一个不可或缺的资源。当我为获得的类提取一个变量并让IDE“修复”它所能修复的一切时,我得到了以下信息:
private static void foo4(Iterable<E1> s) {
Class<? extends E1> aClass = s.iterator().next().getClass();
EnumSet<E1> x = barEnum(aClass);
}
错误消失了,因为现在它接受了
Enum
的子类。发生了两件事。首先,如果您查看getClass
的javadoc,它会说:
由于动态链接,实际的结果类型是
classe,甚至final
类在运行时也可以有子类。所以具体的枚举是final
应该无关紧要。这似乎是编译器无法推断T
(因为原始调用没有有效的T
)的问题。但是您的解决方案是正确的。不应该getClass()
returnClass@shmosel是的,应该是这样。但这不是我必须在非泛型方法中将强制转换添加到类
的原因吗,如上一段所述?@Jens是有道理的。您是否尝试将其分配给EnumSet@shmosel我不知道你是什么意思?在foo3
getClass
中,返回一个Class@Jens我指的是foo4
。
private static void foo4(Iterable<E1> s) {
Class<? extends E1> aClass = s.iterator().next().getClass();
EnumSet<E1> x = barEnum(aClass);
}
private static <T extends Enum<T>> EnumSet<T> barEnum(Class<? extends T> x) {