Java var 和推理类型歧义

Jea*_*nès 16 java type-inference java-10

两个调用都是正确的:

Collectors.groupingBy((String s)->s.toLowerCase(),Collectors.counting());
Collectors.groupingBy((String s)->s.toLowerCase(Locale.ENGLISH),Collectors.counting());
Run Code Online (Sandbox Code Playgroud)

从那以后,为什么下面一个是错误的:

Collectors.groupingBy(String::toLowerCase,Collectors.counting());
Run Code Online (Sandbox Code Playgroud)

毕竟String::toLowerCase不能对应第二个……那为什么IntelliJ会Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match说呢?

String::toLowerCase必须明确解决(String s)->s.toLowerCase()还是我错过了什么?

当然,如果我为 IntelliJ 添加更多上下文,例如:

Collector<String,?,Map<String,Long>> c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());
Run Code Online (Sandbox Code Playgroud)

这是正确的,但是在 Java 10 var 推理类型上下文中这是错误的:

var c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());
Run Code Online (Sandbox Code Playgroud)

我知道编译器无法推断counting. 如果我写:

Collector<String,?,Long> counter = Collectors.counting();
var c = Collectors.groupingBy(String::toLowerCase,counter);
Run Code Online (Sandbox Code Playgroud)

它是正确的。因此,为什么编译器不能推断出唯一可接受的形式?

- - - -编辑 - - - -

我交替使用 IntelliJ/编译器只是因为我首先使用 IntelliJ 并且报告的错误是:

Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match
Run Code Online (Sandbox Code Playgroud)

编译器的错误更难以理解(但包含更多关于推理失败原因的提示),例如:

Demo.java:31: error: incompatible types: cannot infer type-variable(s) T#1,K,A,D,CAP#1,T#2
        Collectors.groupingBy(String::toLowerCase,Collectors.counting());
                             ^
    (argument mismatch; invalid method reference
      incompatible types: Object cannot be converted to Locale)
  where T#1,K,A,D,T#2 are type-variables:
    T#1 extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    K extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    A extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    D extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    T#2 extends Object declared in method <T#2>counting()
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
Run Code Online (Sandbox Code Playgroud)

Eug*_*ene 8

这是编译器的“弱点”,至少在这个 JEP 到位之前是这样

我已经在这里回答了几乎完全相同的问题。JDK 核心开发人员也有另一个答案

还有另一个问题与您的问题非常接近。

重要的是,这是已知会导致一个问题,有时,却有着平凡的解决方案-使用lambda,因此一个明确的类型,根据JLS