调用具有不同T类的print(List a,T b)时发生错误

我正在尝试学习Java Generics,并找到了以下代码。

public static  void print(T a, T b){ System.out.println(a); System.out.println(b); } public static void main(String[] args){ print(new ArrayList(), 1); } 

哪个没有问题。

但是,当我将print方法更改为以下内容时,它会给我编译错误。

 public static  void print(List a, T b){ System.out.println(a); System.out.println(b); } 

错误:

 GenericTest.java:9: error: method print in class GenericTest cannot be applied to given types; print(new ArrayList(), 1); ^ required: List,T found: ArrayList,int reason: no instance(s) of type variable(s) T exist so that argument type int conforms to formal parameter type T where T is a type-variable: T extends Object declared in method print(List,T) 1 error 

任何人都可以帮我理解错误吗?

您应该首先了解的是,使用以下方法签名

 public static  void print(T a, T b) 

两个T 必须是相同的类型,也就是说ab都具有相同的推理类型。

那么为什么它适用于new ArrayList()1 ? 因为这两个参数实际上可以表示为Serializable ,这是最近的常见超类型ArrayListInteger

  • ArrayList实现Serializable接口。
  • 1可以装入Integer ,也可以是Serializable

所以在这种情况下,编译器会将T推断为Serializable


在第二种情况下,签名

 public static  void print(List a, T b) 

没有常见的超类型TListInteger都有效。 确实, StringInteger都是Serializable ,但由于generics不是多态的 ,所以它不起作用。

编辑:它没有像我之前提到的那样解析为Object,而是解决了Serializable问题。 请参阅Tunaki的正确答案 。

在第一种情况下, T被解析为最具体的类型,可以引用您的参数。

在您的示例中,它将被解析为Object Serializable ,因为ArrayListInteger都是Object Serializable子类型。

但是在第二个例子中,你有一个List作为参数……

现在,当您使用ArrayList调用它时,类型T被解析为String 。 它无法解析为任何其他类型,因为ArrayList ArrayList 不是 ArrayList的超类型

您可以通过以下方式调用该方法:

 print(new ArrayList(), "SimpleString"); 

要么

 print(new ArrayList(),5) 

因为是一个类型,它不能同时是String和integer。

如果您执行以下操作,您的电话可能会有效:

 public static  void print(List a, K b){ System.out.println(a); System.out.println(b); } public static void main(String[] args){ print(new ArrayList(),1); }