[英]How to avoid type casting while passing generic Collection to legacy method?
我有以下代码
public class GenericTest {
public <T extends Number> void someMethod(){
Map<T, String> map = new HashMap<>();
someLegacyMethod(map.keySet()); // COMPILER ERROR
}
public String someLegacyMethod(Set<Number> nums){
//some logic
return "";
}
}
我期望可以像T是Number类型那样直接调用someLegacyMethod。 但是编译器给我一个错误。
The method someLegacyMethod(Set<Number>) in the type GenericTest is not applicable for the arguments (Set<T>)
因此,要么我不得不修改传统方法以使用它的类型参数,要么每次调用该方法时都强制转换方法参数。 上面的代码为什么不起作用? 还有其他更清洁的方法可以完成这项工作吗?
问题在于Set<T extends Number>
(来自映射)和Set<Number>
( someLegacyMethod
参数)之间的someLegacyMethod
。
T extends Number
可以在运行时用Integer
, Long
, Double
等替换,然后map.keySet()
将分别返回Set<Integer>
, Set<Long>
和Set<Double>
。
现在存在的问题是
Set<Double>
(例如)是Set<Number>
的子类吗?
根据someLegacyMethod()
的名称,我可以假定您无法为其引入泛型类型。 您唯一可以做的就是将键集的内容复制到Set<Number>
:
public <T extends Number> void someMethod() {
Map<T, String> map = new HashMap<>();
Set<Number> set = new HashSet<Number>(map.keySet());
someLegacyMethod(set);
}
map.keySet()
返回您的someLegacyMethod Set<Number>
更改为Set<T>
的类型为T
的键集。
您应该创建一个新的包装器方法,该方法检查是否为instanceOf或抛出非法的ArgumentException。
public String wrapperOfSomeLegacyMethod(Set<T extends Number> nums) throws IllegalArgumentException{
//itervate over num. check if isntance of Number
//if yes, call someLegacyMethod
//if no , throw illegalArgumentException
}
因为它不识别T
我会这样:
public class GenericTest <T extends Number> {
public T void someMethod(){
Map<T, String> map = new HashMap<>();
someLegacyMethod(map.keySet()); // COMPILER ERROR
}
public String someLegacyMethod(Set<T> nums){
//some logic
return "";
}
}
然后以这种方式实例化您的班级:
new GenericText<ExtendsNumber>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.