Javac推断方法T
中的String
为f()
。语言规范中的哪些规则可以得出结论?
<T> T g(){ return null; }
String f()
{
return g();
}
答案 0 :(得分:9)
我怀疑编译器正在有效地使用section 15.12.2.8:
如果方法结果发生在将要进行赋值转换(第5.2节)的上下文中,那么让R成为方法的声明结果类型
这是将return语句视为需要进行赋值转换。例如,假设我们将f()
转换为:
String f()
{
String tmp = g();
return tmp;
}
现在关于 是否需要进行赋值转换,section 14.17(return语句)包含:
带有Expression的return语句必须包含在声明为返回值(第8.4节)或发生编译时错误的方法声明中。 Expression必须表示某种类型T的变量或值,否则会发生编译时错误。类型T必须是可分配的(第5.2节)到方法的声明结果类型,否则会发生编译时错误。
对5.2的引用是“赋值转换”部分,所以我猜这意味着表达式g()
“受赋值转换”,导致第15.12节的那一部分。 2.8适用。
答案 1 :(得分:0)
T被推断为一个String,因为g()的泛型返回类型被用作f()的返回类型,它强烈地键入String。为了使语句有效,T必须是String,所以它是。
答案 2 :(得分:0)
因为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将编译正常,因为它从返回类型推断出类型。我不会编译,因为类型不匹配。