Java var 和推理类型歧义 [英] Java var and inference type ambiguity
问题描述
两个调用都是正确的:
Collectors.groupingBy((String s)->s.toLowerCase(),Collectors.counting());
Collectors.groupingBy((String s)->s.toLowerCase(Locale.ENGLISH),Collectors.counting());
从那以后,为什么下面一个是错误的:
Since then, why the following one is wrong:
Collectors.groupingBy(String::toLowerCase,Collectors.counting());
毕竟 String::toLowerCase
不能对应第二个...那为什么 IntelliJ 说 Reference to 'toLowerCase' 不明确,'toLowerCase(Locale)' 和 'toLowerCase()' 匹配
?
after all String::toLowerCase
can not correspond to the second one... Then why IntelliJ says Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match
?
String::toLowerCase
必须明确解析为 (String s)->s.toLowerCase()
还是我遗漏了什么?
String::toLowerCase
must be unambiguously resolved to (String s)->s.toLowerCase()
or did I miss something?
当然,如果我为 IntelliJ 添加更多上下文,例如:
Of course if I put more context to IntelliJ like:
Collector<String,?,Map<String,Long>> c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());
这是正确的,但是在 Java 10 var 推理类型上下文中它是错误的:
that is correct, but alas in Java 10 var inference type context it is wrong:
var c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());
我知道编译器无法推断counting
的输入类型.如果我写:
I understand that compiler can not infer the input type of counting
. If I write:
Collector<String,?,Long> counter = Collectors.counting();
var c = Collectors.groupingBy(String::toLowerCase,counter);
它是正确的.因此,为什么编译器不能推断出唯一可接受的形式?
it it correct. Thus again, why compiler is not able to infer the only acceptable form?
-------EDIT--------
-------EDIT--------
我交替使用 IntelliJ/编译器只是因为我首先使用 IntelliJ 并且报告的错误是:
I used IntelliJ/compiler interchangeably just because I used IntelliJ first and error reported was :
Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match
编译器的错误更难以理解(但包含更多关于推理失败原因的提示),例如:
Compiler's error was much much more unreadable (but contains more hints on why inference fails), something like:
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 ?
推荐答案
这是编译器的弱点",至少在 此 JEP 已就绪.
This is compiler "weakness", at least until this JEP is in place.
我已经在此处回答了几乎完全相同的问题.还有另一个JDK核心开发人员的回答.
I have already answered almost the same exact question here. There is also another answer from JDK core developers too.
还有还有另一个问题非常接近你的.
重要的是,这有时会导致问题,但有一个简单的解决方案 - 使用 lambda
,因此是 explicit 类型,根据JLS
.
What matters is that this is known to cause a problem, at times, but has a trivial solution - use a lambda
, and thus an explicit type, according to the JLS
.
这篇关于Java var 和推理类型歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!