Java泛型类型推断疑问:为何pick方法参数为Serializable?s编译s1不编译?
Java泛型类型推断疑问
先看这段泛型代码:
static <T> T pick(T a1, T a2) { return a2; } Serializable s = pick("d", new ArrayList<String>()); // 编译通过 String s1= pick("d", new ArrayList<String>()); // 编译失败
问题1:类型推断为何判定传递给pick方法的第二个参数类型为Serializable?
Java泛型的类型推断会选取两个参数的最具体公共父类型作为泛型参数T的实际类型。这里:
- 第一个参数
"d"是String类型,它实现了Serializable、Comparable<String>等接口 - 第二个参数
new ArrayList<String>()是ArrayList<String>类型,它实现了Serializable、Collection<String>等接口
两者的公共父类型里,Serializable是最具体的、能同时覆盖两个参数类型的类型之一(另一个是Object,但编译器会优先选择更具体的匹配类型)。所以最终推断出的T是Serializable,第二个参数ArrayList<String>本身实现了Serializable,自然可以被当作Serializable类型处理。
问题2:为何变量s的代码可以编译,而变量s1的代码无法编译?
- 变量
s的类型是Serializable,而pick方法推断出的返回类型正是Serializable,类型完全匹配,所以编译通过。 - 变量
s1的类型是String,但pick方法的返回类型是Serializable。虽然String实现了Serializable,但Serializable接口的实例不一定是String(这里返回的实际是ArrayList<String>对象,显然不是String),编译器不允许将Serializable类型直接赋值给String类型,因此编译失败。
内容的提问来源于stack exchange,提问作者Save Soil
相关产品推荐
相关产品推荐

