为什么上下文在这个Java 8流示例中是静态的?

Ili*_*kis 11 java java-8 java-stream

在Java 8中使用以下简单方法:

public void test(){

    Stream<Integer> stream = Stream.of(1,2,3);
    stream.map(Integer::toString);
}
Run Code Online (Sandbox Code Playgroud)

我得到两个错误:

java:不兼容类型:无法推断类型变量R(参数不匹配;无效方法引用

对toString的引用在java.lang.Integer中的方法toString(int)和java.lang.Integer中的方法toString()都是不明确的

并且:

无效方法引用非静态方法toString()不能从静态上下文引用

第一个错误是可以理解的,Integer类有两个方法:

public static String toString(int i)
public String toString()
Run Code Online (Sandbox Code Playgroud)

并且编译器无法推断出所需的方法引用.

但是关于第二个问题,编译器引用的静态上下文在哪里?

该错误与Integer类的方法toString()有关,它不是静态的,但为什么我使用map()调用该方法的上下文是静态的?

还有一个问题,如果编译器必须解决导致编译时错误的两种方法之间的歧义,那么他不应该选择另一种吗?

Nec*_*aux 5

第二个错误是红鲱鱼.它揭示了编译器的一些内部工作原理.问题在于存在歧义问题,第二个问题是其结果,可以忽略.它可能做的是如下.

  1. 它检查是否存在与"有效"签名匹配的静态方法.有,所以它假设静态是要走的路.这强烈暗示编译器中对静态方法存在各种"偏好",尽管这可能是任意的.

  2. 然后它会找到匹配签名的第一种方法.它不是静态的,所以它变得混乱,因为它以前DID找到一个带有该签名的静态方法.

在混合的某处,它也发现引用是模糊的.不清楚步骤1或2是否发生这种情况,但编译器不会中止,因为它试图提供帮助并发现进一步的编译错误.

从理论上讲,编译器可以更好地处理这个问题,因为第二条消息令人困惑.

注意:Eclipse编译器不显示第二个错误.