为什么在这种情况下需要演员表?
Why a cast is necessary in this case?
假设我有一个具有以下签名的方法:
public static <T> Set<Class<? extends T>> dosomething(Class<T> clazz)
如果我尝试使用通配符 class 调用它,如下例所示
Class<?> clazz = Integer.class
Set<Class<?>> result = dosomething(clazz);
编译器抱怨如下:
Error: incompatible types: inference variable T has incompatible equality constraints java.lang.Object,capture#1 of ?
因此,解决方法是在方法调用中添加强制转换。
Set<Class<?>> result = (Set<Class<?>>) dosomething(clazz);
我想知道为什么在这种特殊情况下需要强制转换,以及是否有任何解决方法可以避免强制转换...
我为此使用 java-8。
谢谢
问题似乎是 Set<Class<?>> result
中的通配符类型参数,而您的方法 returns Set<Class<? extends T>>
因此,结果可以包含 Class-任何类型的对象(Object 的子类型),该方法仅包含 returns T 的子类型的对象(如编译器错误中所述)。
这一个
public static void main(String[] args) {
Class<?> clazz = Integer.class;
Set<Class<?>> result = dosomething(clazz);
}
public static <T> Set<Class<?>> dosomething(Class<T> clazz){
return new HashSet<Class<?>>();
}
或这个
public static void main(String[] args) {
Class<Integer> clazz = Integer.class;
Set<Class<? extends Integer>> result = dosomething(clazz);
}
public static <T> Set<Class<? extends T>> dosomething(Class<T> clazz){
return new HashSet<Class<? extends T>>();
}
将正常工作。
在您的代码中,由于类型擦除,编译器无法确定您的代码在运行时是否正确,因此会报错。
假设我有一个具有以下签名的方法:
public static <T> Set<Class<? extends T>> dosomething(Class<T> clazz)
如果我尝试使用通配符 class 调用它,如下例所示
Class<?> clazz = Integer.class
Set<Class<?>> result = dosomething(clazz);
编译器抱怨如下:
Error: incompatible types: inference variable T has incompatible equality constraints java.lang.Object,capture#1 of ?
因此,解决方法是在方法调用中添加强制转换。
Set<Class<?>> result = (Set<Class<?>>) dosomething(clazz);
我想知道为什么在这种特殊情况下需要强制转换,以及是否有任何解决方法可以避免强制转换... 我为此使用 java-8。 谢谢
问题似乎是 Set<Class<?>> result
中的通配符类型参数,而您的方法 returns Set<Class<? extends T>>
因此,结果可以包含 Class-任何类型的对象(Object 的子类型),该方法仅包含 returns T 的子类型的对象(如编译器错误中所述)。
这一个
public static void main(String[] args) {
Class<?> clazz = Integer.class;
Set<Class<?>> result = dosomething(clazz);
}
public static <T> Set<Class<?>> dosomething(Class<T> clazz){
return new HashSet<Class<?>>();
}
或这个
public static void main(String[] args) {
Class<Integer> clazz = Integer.class;
Set<Class<? extends Integer>> result = dosomething(clazz);
}
public static <T> Set<Class<? extends T>> dosomething(Class<T> clazz){
return new HashSet<Class<? extends T>>();
}
将正常工作。
在您的代码中,由于类型擦除,编译器无法确定您的代码在运行时是否正确,因此会报错。