我最近在重构代码时遇到了这个问题:
下面的方法"getList()"具有参数化的返回类型.在下面,我已经放了三个试图隐式绑定的<T>方法<Integer>.
我无法弄清楚为什么前两个编译和运行正确,而第三个(bindViaMethodInvocation)甚至不会编译.
有线索吗?
在StackOverflow上寻找类似的问题时,我遇到了这个问题: 返回类型的推断通配符泛型.那里的答案(信用Laurence Gonsalves)有几个有用的参考链接来解释应该发生的事情: "这里的问题(正如你的建议)是编译器正在执行捕获转换.我相信这是结果JLS的JLS 的§15.12.2.6."
package stackoverflow;
import java.util.*;
public class ParameterizedReturn
{
// Parameterized method
public static <T extends Object> List<T> getList()
{
return new ArrayList<T>();
}
public static List<Integer> bindViaReturnStatement()
{
return getList();
}
public static List<Integer> bindViaVariableAssignment()
{
List<Integer> intList = getList();
return intList;
}
public static List<Integer> bindViaMethodInvocation()
{
// Compile error here
return echo(getList());
}
public static List<Integer> echo(List<Integer> intList)
{
return intList;
}
}
Run Code Online (Sandbox Code Playgroud)
前两个方法getList()在用于赋值转换的上下文中使用- List<Integer>从返回的方法赋值或返回语句List<Integer>.同样是不真正对bindViaMethodInvocation-使用表达式作为方法的参数是不受到分配的转换.
如果没有从实际参数的类型推断出任何方法的类型参数,现在推断它们如下.
- 如果方法结果发生在它将受到赋值转换(第5.2节)到类型S的上下文中,那么让R成为方法的声明结果类型,并让R'= R [T1 = B(T1) ...... Tn = B(Tn)]其中B(Ti)是上一节中Ti的推断类型,如果没有推断出类型,则推断Ti.
JLS不清楚为什么返回语句在这里计算.我能找到的最接近的是14.17:
带有Expression的return语句必须包含在声明为返回值(第8.4节)或发生编译时错误的方法声明中.Expression必须表示某种类型T的变量或值,否则会发生编译时错误.类型T必须可赋值(第5.2节)到方法的声明结果类型,否则会发生编译时错误.
(如果第5.2节指出,return语句这将是很好是受分配转换).