为什么推理会确定传递给pick方法的第二个参数的类型是Serializable?为什么s编译但s1行不编译
static <T> T pick(T a1, T a2) { return a2; }
Serializable s = pick("d", new ArrayList<String>()); //this works
String s1= pick("d", new ArrayList<String>());//doesnt compile
因为结果和两个参数必须是相同的类型-T
。
在第二个示例中,结果是String,第一个参数是String,但第二个参数是ArrayList。字符串!=阵列列表
在第一个示例中,第一个参数是String(String实现Serializable
接口(,第二个参数是ArrayList,但List实现Serializable。因此,结果也可以是Serializable——这是所有这3个对象的共同点。
对于方法的每次调用,编译器都需要推断出pick()
类型T
。
代码片段中pick()
的两个调用都是所谓的poly表达式(即对上下文敏感(,因为它们出现在赋值上下文中。因此,在这两种情况下,目标类型都可以从分配上下文:中推断出来
-
在第一种情况下,目标类型是
Serializable
,编译器成功地执行了两个参数(String
和ArrayList<String>
(到Serializable
的加宽对流,因为它是两者的超类型; -
在第二种情况下,类型参数
T
的目标类型是String
,并且编译器由于未能将ArrayList<String>
的第二个参数转换为String
而发出编译错误,这些类型是不相关的。