我有一个函数,其参数是:
myFn(String, List<Number>, List<Number>)
调用函数有两个List对象,我想用它作为函数的第二个和第三个参数。我收到编译错误:
The method myFn(String, List<Number>, List<Number>) in the type MyLib is not applicable for the arguments (String, List<Double>, List<Double>)
有没有一种简单的方法可以解决这个问题?有没有一种简单的方法可以将Double列表转换为数字列表?
答案 0 :(得分:9)
您无法将List<Double>
投射到List<Number>
,因为以下代码会破坏您的List<Double>
List<Double> list = new List<Double>();
List<Number> list1 = list; // This does not work
list1.add(new Integer(0));
Double d = list.get(0);// Hu-hoh you received an Integer, not a Double!!
List<? extends Number> list2 = list; // This does work
你能做什么,就是改变
myFn(String, List<Number>, List<Number>)
到
myFn(String, List<? extends Number>, List<? extends Number>)
答案 1 :(得分:4)
将myFn定义更改为<T extends Number> myFn(String, List<T>, List<T>, Class<T> type)
你可以将其称为myFn(String, List<Double>, List<Double>, Double.class)
答案 2 :(得分:1)
如果您无法更改myFn
方法,则可以选择作弊:
private <returntype> myFnAdapter(String s , List<Double> l1Double, List<Double> l2Double) {
// the following lines do create warnings
// it's safe, because all list items always extend Number.
List l1TypeErased = l1Double;
List<Number> l1Number = l1TypeErased;
List l2TypeErased = l2Double;
List<Number> l2Number = l2TypeErased;
return myFn(s, l1Number, l2Number);
}
你应该看到一些警告,就是这样。但是我们知道我们得到了Double
的列表,并且这些列表的所有项都扩展了Number
,所以它不会在运行时造成麻烦。只需添加注释即可解释类型擦除。然后将所有值复制到新列表会更便宜。
答案 3 :(得分:1)
您可以使用
myFn(String, List<? extends Number>, List<? extends Number>)
或使用
调用您的函数myFn(String, (List) list1, (List) list2); // produces a warning.
答案 4 :(得分:1)
你不能像这样投射集合。 This Java tutorial为您提供了完整的解释。
作为一个解决方案,在调用方法时,只需创建一个以Double List作为参数的新List:
List<Double> doubleList = new ArrayList<Double>();
myFn(new ArrayList<Number>(doubleList));
答案 5 :(得分:1)
如果您知道该方法不会修改该列表,请使用
List<Number> unmodifiableView = Collections.unmodifiableList(doubleList);
以恒定时间运行并返回视图。它是完全类型安全,高效和合法的 - 只要您知道列表不会被修改。