Java 泛型,传递错误的类型?

Java 泛型,传递错误的类型?,java,generics,Java,Generics,最后两种说法有什么不同?为什么一个语句有效而另一个不有效 package Main; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Main { public static void printIt(List<Object> l) { System.out.println(l); } public

最后两种说法有什么不同?为什么一个语句有效而另一个不有效

package Main;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void printIt(List<Object> l)
    {
        System.out.println(l);
    } 

    public static void main(String[] args) {
        List<String> l =new ArrayList<>();
        l.add("A");

        //what is the differance between the following statments ? 

        printIt(Arrays.asList("A")); // it compiles successfully
        printIt(l); // it does not compile

    }
}
packagemain;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
公共班机{
公共静态无效打印(列表l)
{
系统输出打印LN(l);
} 
公共静态void main(字符串[]args){
列表l=新的ArrayList();
l、 添加(“A”);
//以下陈述有什么不同?
printIt(Arrays.asList(“A”);//编译成功
printIt(l);//它不编译
}
}

这是因为您的方法需要一个
列表,而您给它一个
列表

尽管你第一次读到这篇文章时会觉得很奇怪,
列表
不是
列表

在您的示例中,您不需要修改列表的内容,但让我们设想一种方法,您希望在其中添加新元素

public static void addIt(List<Object> l, Object o)
{
    l.add(o);
} 
public static void main(String[] args) {
    List<String> l =new ArrayList<>();
    l.add("A");
    addIt(l, new Integer(1)); // What?! you want to add an Integer to a List<String>!!!!
}
printIt(Arrays.asList(“A”))
的情况有点不同。这是因为泛型是通过泛型方法动态确定的

List<Object> l = Arrays.asList("A"); //this is valid, the generic type is determined from the type we expect in this declaration.
List l=Arrays.asList(“A”)//这是有效的,泛型类型是根据我们在此声明中期望的类型确定的。

问题是
printIt()
方法期望
List
作为参数,但我们正在将
List
传递给它,这就是编译问题的原因。 替换方法printIt()中的参数列表,如下所示:

    public static void printIt(List<? extends Object> l)
    {
        System.out.println(l);
    }

publicstaticvoidprintit(List为了帮助您了解这一点,下面是另一个编译代码示例,演示了从返回类型推断类型:

import java.util.*;
//我们的主类变成了一个文件,但主方法仍然存在
公共类HelloWorld
{
公共静态void main(字符串[]args)
{
foo(createList());//T必须是对象
}
私有静态void foo(List objs){}
私有静态列表createList(){返回新的ArrayList();}
}

正如@csharpfolk提到的,这一切都是关于“类型推断”!
下面的文档可能有助于理解其背后的想法


列表l=new ArrayList()可能重复;无论如何都不会编译,因为ArrayList没有声明类型。@Jankapunkt它会编译,这是Java 7中引入的菱形运算符。
List
不可分配给
List
,例如,如果您有
List
,则可以添加值3,该值对strings@Nour.kotmawi调用
printIt(Arrays.asList(“A”);
默认为
打印它(Arrays.asList(“A”);
不为
打印它(Arrays.asList(“A”);
这对我来说很明显,但对打印它(Arrays.asList(“A”));不应该编译!!@Nour.kotmawi很抱歉我忘记了这一部分。我完成了我的answer@Nour,我使用的是Java-7,在我的机器上,两行代码都没有编译,并且给出了相同的编译错误,表示:printIt()requires List和List无法应用,这是因为Java 7中的类型推断仍然有点弱。Java 8中的类型推断已经得到了改进。您需要使用
printIt(Arrays.asList(“a”);
来处理Java 7。
    public static void printIt(List<? extends Object> l)
    {
        System.out.println(l);
    }
import java.util.*;

// our main class becomes a file but the main method is still found
public class HelloWorld
{
  public static void main(String[] args)
  {
    foo(createList()); // T must be Object
  }

  private static void foo(List<Object> objs) { }

  private static <T> List<T> createList() { return new ArrayList<>(); }
}