【发布时间】:2021-02-19 13:54:40
【问题描述】:
两个调用都是正确的:
Collectors.groupingBy((String s)->s.toLowerCase(),Collectors.counting());
Collectors.groupingBy((String s)->s.toLowerCase(Locale.ENGLISH),Collectors.counting());
从那以后,为什么下面的错误:
Collectors.groupingBy(String::toLowerCase,Collectors.counting());
毕竟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());
这是正确的,但是在 Java 10 var 推断类型上下文中它是错误的:
var c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());
我了解编译器无法推断counting 的输入类型。如果我写:
Collector<String,?,Long> counter = Collectors.counting();
var c = Collectors.groupingBy(String::toLowerCase,counter);
它是正确的。因此,为什么编译器不能推断出唯一可接受的形式?
-------编辑--------
我交替使用 IntelliJ/compiler 只是因为我首先使用 IntelliJ 并且报告的错误是:
Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match
编译器的错误更加难以理解(但包含更多关于推理失败原因的提示),例如:
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 ?
【问题讨论】:
-
在我看来是个错误。
-
“那么为什么 IntelliJ 说”你是说这只发生在 intellij 中,还是它也发生在另一个编译器中?
-
Eclipse 上也一样:编译器似乎将
Collectors.counting()的类型参数推断为Object,因此它期望String有一个方法toLowerCase(Object)。 -
Netbeans 上的 Java 14,此处为 Windows。同样的问题。如果我对方法引用进行类型转换,编译器错误就会消失:
(Function<String, String>) String::toLowerCase。 -
@AndyTurner 实际上编译器会报告错误,这些错误由 intellij “解释”以使它们更“可读”。
标签: java type-inference java-10