最近在重构代码的时候遇到了这个问题:
下面的方法“getList()”有一个参数化的返回类型。在此之下,我放置了三种尝试隐式绑定(bind) <T>
的方法。至 <Integer>
.
我不明白为什么前两个可以正确编译和运行,而第三个 (bindViaMethodInvocation) 甚至不能编译。
有什么线索吗?
在 StackOverflow 上寻找类似问题时,我遇到了这个问题: Inferred wildcard generics in return type .那里的答案(信用 Laurence Gonsalves)有几个有用的引用链接来解释应该发生的事情: “这里的问题(如您所建议的)是编译器正在执行 Capture Conversion。我相信这是 JLS 的 §15.12.2.6 of the JLS 的结果。”
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;
}
}
最佳答案
前两种方法使用getList()
在受赋值转换约束的上下文中 - 要么赋值给 List<Integer>
或返回 List<Integer>
的方法的 return 语句. bindViaMethodInvocation
同样不是 - 使用表达式作为方法参数不受赋值转换的影响。
If any of the method's type arguments were not inferred from the types of the actual arguments, they are now inferred as follows.
- If the method result occurs in a context where it will be subject to assignment conversion (§5.2) to a type S, then let R be the declared result type of the method, and let R' = R[T1 = B(T1) ... Tn = B(Tn)] where B(Ti) is the type inferred for Ti in the previous section, or Ti if no type was inferred.
JLS 并不清楚为什么 return 语句在这里很重要。我能找到的最接近的是 14.17 :
A return statement with an Expression must be contained in a method declaration that is declared to return a value (§8.4) or a compile-time error occurs. The Expression must denote a variable or value of some type T, or a compile-time error occurs. The type T must be assignable (§5.2) to the declared result type of the method, or a compile-time error occurs.
(如果第 5.2 节声明 return 语句受赋值转换的约束,那就太好了。)
关于java - 为什么参数化方法在某些情况下可以隐式绑定(bind)而不是其他情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5553451/