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) { 
    }
}
  • 我怎样才能有效地/很好地(在不构建新列表的情况下)解决这个问题
  • 这个语言设计决策的基本原理是什么
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;
导入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
列表。但是,如果需要确保(例如)两个不同参数之间的类型相同,则只要不在其他任何地方使用类型绑定参数,就没有区别(或者,比方说,您希望返回相同的
编号
-扩展类型的列表),那么您必须使用下面的方法。