调用具有不同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
必须是相同的类型,也就是说a
和b
都具有相同的推理类型。
那么为什么它适用于new ArrayList
和1
? 因为这两个参数实际上可以表示为Serializable
,这是最近的常见超类型ArrayList
和Integer
:
-
ArrayList
实现Serializable
接口。 -
1
可以装入Integer
,也可以是Serializable
。
所以在这种情况下,编译器会将T
推断为Serializable
。
在第二种情况下,签名
public static void print(List a, T b)
没有常见的超类型T
对List
和Integer
都有效。 确实, String
和Integer
都是Serializable
,但由于generics不是多态的 ,所以它不起作用。
编辑:它没有像我之前提到的那样解析为Object,而是解决了Serializable问题。 请参阅Tunaki的正确答案 。
在第一种情况下, T
被解析为最具体的类型,可以引用您的参数。
在您的示例中,它将被解析为Object
Serializable
,因为ArrayList
和Integer
都是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); }