繁体   English   中英

在将通用Collection传递给旧方法时,如何避免类型转换?

[英]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可以在运行时用IntegerLongDouble等替换,然后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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM