Java:为什么可以';t列表<;整数>;是否传递给函数(列表<;编号>;)?
为什么我们不能将Java:为什么可以';t列表<;整数>;是否传递给函数(列表<;编号>;)?,java,Java,为什么我们不能将List传递给具有List的函数?对于正态变量,这是可能的 考虑下面的MWE。为什么我们可以将整数传递给带有数字参数的函数,而不能将列表传递给列表 问题: import java.util.ArrayList; import java.util.List; public class Tester { public static void main(String[] args) { Integer i = new Integer(2); /
List
传递给具有List
的函数?对于正态变量,这是可能的
考虑下面的MWE。为什么我们可以将整数
传递给带有数字
参数的函数,而不能将列表
传递给列表
问题:
import java.util.ArrayList;
import java.util.List;
public class Tester {
public static void main(String[] args) {
Integer i = new Integer(2);
// This works fine.
processNumber(i);
List<Integer> l = new ArrayList<Integer>();
// ERROR "The method processNumberList(List<Number>) in the type
// Tester is not applicable for the arguments (List<Integer>)"
processNumberList(l);
}
private static void processNumber(Number n) {
}
private static void processNumberList(List<Number> l) {
}
}
- 我怎样才能有效地/很好地(在不构建新列表的情况下)解决这个问题李>
- 这个语言设计决策的基本原理是什么李>
import java.util.ArrayList;
import java.util.List;
public class Tester {
public static void main(String[] args) {
Integer i = new Integer(2);
// This works fine.
processNumber(i);
List<Integer> l = new ArrayList<Integer>();
// ERROR "The method processNumberList(List<Number>) in the type
// Tester is not applicable for the arguments (List<Integer>)"
processNumberList(l);
}
private static void processNumber(Number n) {
}
private static void processNumberList(List<Number> l) {
}
}
import java.util.ArrayList;
导入java.util.List;
公共类测试员{
公共静态void main(字符串[]args){
整数i=新整数(2);
//这个很好用。
工艺编号(i);
列表l=新的ArrayList();
//错误“类型中的方法processNumberList(列表)”
//测试仪不适用于参数(列表)”
进程编号列表(l);
}
私有静态无效进程号(编号n){
}
私有静态void processNumberList(列表l){
}
}
我如何高效/良好地(不构建新列表)工作
围绕着这个
只需将方法的签名更改为next:
private static <T extends Number> void processNumberList(List<T> l) {
}
private static void processNumberList(列表l){
}
用以下内容替换您的声明:
private static void processNumberList(List<? extends Number> l) {...}
private static void processNumberList(列表),因为您的函数可能会尝试将非整数放入列表中。需要理解的关键问题(重复链接中的第二个答案)-是java泛型是不变的;不是协变的。当你深入研究时,你会发现java数组实际上是协变的;这有一些好的方面,但会导致很多问题。因此,java的父亲们决定在添加泛型时不重复这个“错误”。public void thiswowbeevil(List List){List.add(Double.valueOf(Math.PI));}
ThisWouldbeivil(MyListFinTegers);
现在PI在您的整数列表中。为什么这个“T扩展数”放在空之前?这个语言构造是什么时候引入的?这个构造和(列表l)它是一个类型参数化方法有什么区别?您可以有方法(与类相反)是类型参数化的。我认为这个“void”有误导性,因为它可以给出关于返回类型(void)的指示。为什么要引入此构造?@robert-当您需要类型绑定参数时,后者不会编译:?让我们想象一下,您有一个实用函数,可以在相同类型的列表之间复制元素。它是私有静态void copyElements(列表x,列表y)
。但您希望确保两个列表的类型相同。通用方法用于此-您可以拥有一个签名私有静态void copyElements(列表x,列表y)
。啊哈,是的,我已经发现了。但现在我想知道下面的Beri方法和Nicolas方法的区别是什么?这种方法说“给我一个扩展Number
”的列表。下面的方法是”对于扩展了Number
的任何给定类型T
,请给我一个类型T
列表。但是,如果需要确保(例如)两个不同参数之间的类型相同,则只要不在其他任何地方使用类型绑定参数,就没有区别(或者,比方说,您希望返回相同的编号
-扩展类型的列表),那么您必须使用下面的方法。