Javac 推断 f()
方法中的 T
为 String
。语言规范中的哪些规则导致了这个结论?
<T> T g(){ return null; }
String f()
{
return g();
}
f()
转换为:String f()
{
String tmp = g();
return tmp;
}
对5.2的引用是“赋值转换”部分,因此我想这意味着表达式带表达式的返回语句必须包含在声明为返回值的方法声明中(§8.4),否则会出现编译时错误。表达式必须表示某种类型T的变量或值,否则会出现编译时错误。类型T必须可分配(§5.2)到方法的声明结果类型,否则会出现编译时错误。
g()
受到“赋值转换”的影响,导致第15.12.2.8节的那一部分适用。由于g是一个通用方法,Java会推断出g的类型以匹配f的返回类型。
你可以通过尝试以下三个函数来了解这一点。
class SomeClass{
<T> T g(){return null;}
String f() {
return this.<String>g();
}
Integer h() {
return this.<Integer>g();
}
Integer i() {
return this.<String>g();
}
}
f和h将编译成功,因为它从返回类型推断类型。i将无法编译,因为类型不匹配。
由于g()的泛型返回类型被用作f()的返回类型,并且f()已经被强制类型化为String,因此T被推断为一个字符串。为了使语句有效,T必须是一个字符串,因此就是这样。