25

为什么编译器能够String在函数返回类型的情况下正确推断类型参数。

public class Generics {
    private static List<String> function() {
        return new ArrayList<>();
    }
}

但是当要推断的类型是方法参数时它会失败:

public class Generics {
    public static void main(String[] args) {
        method(new ArrayList<>());
    }    

    private static void method(List<String> list) {

    }
}

这种情况下的错误是:

The method method(List<String>) in the type Generics is not applicable 
for the arguments (ArrayList<Object>)
4

2 回答 2

16

这是类型推断尚未按预期工作的地方之一。

不幸的是,这种行为是完全有效且符合要求的。

好消息是Java 8将包括改进的类型推断 (JEP 101),所以像这样的情况应该像你期望的那样编译:

当这种泛型方法调用的结果被传递给另一个方法时,编译器应该能够推断类型似乎是合理的 [...]。

不幸的是,这在 JDK 5/6/7 中是不允许的——程序员唯一可用的选择是使用显式类型参数。

除了直接改进(即您在此处提到的情况)之外,此更改对于能够更有效地使用Lambdas (JEP 126)也是必要的(即无需输入大量类型信息)。

于 2013-03-15T15:29:09.830 回答
6

在 JLS 中推断未解析类型参数的部分相当复杂,但我知道第一种情况的菱形出现在它需要进行赋值转换的地方,而在第二种情况下,它出现在方法调用转换中,即遵循不同的规则。

于 2013-03-15T15:33:41.830 回答