Java var and inference type ambiguity

Jean-Baptiste Yunès

Both calls are correct:

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());

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 must be unambiguously resolved to (String s)->s.toLowerCase() or did I miss something?

Of course if I put more context to IntelliJ like:

Collector<String,?,Map<String,Long>> c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());

that is correct, but alas in Java 10 var inference type context it is wrong:

var c = Collectors.groupingBy(String::toLowerCase,Collectors.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--------

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 ?
Eugene

This is compiler "weakness", at least until this JEP is in place.

I have already answered almost the same exact question here. There is also another answer from JDK core developers too.

There is also yet another question that is very close to yours.

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.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Java var and inference type ambiguity

From Dev

Type Casting ambiguity in Java

From Dev

Java type inference with erasure

From Dev

Type inference in java

From Dev

Java Type Inference in Static Methods

From Dev

Java Generics, Type Inference, Inheritance?

From Dev

Generic type inference limits in Java

From Dev

Java type inference of generic exception type

From Dev

Ambiguity error while overloading var args method and wrapper methods in java

From Dev

when use type inference? we can always use VAR?

From Dev

Why is Java's type inference so weak?

From Java

A peculiar feature of exception type inference in Java 8

From Dev

Java 8 and Generalized Target-Type Inference

From Dev

Java 8: Generic type inference improvements

From Dev

Java ternary operator influence on generics type inference

From Dev

Confusion over Java generic method type inference

From Dev

Problems using generics and type inference in Java

From Dev

Reflection type inference on Java 8 Lambdas

From Dev

Very confused by Java 8 Comparator type inference

From Dev

Make java compiler output type inference information

From Dev

Java type inference with lower bounded types

From Dev

How does java type inference work?

From Dev

Java/Scala Bounded Generics and type inference mismatch

From Dev

Java 10 Local Variable Type Inference Advantage?

From Dev

Java6, Guava, generics, type inference

From Dev

Java 8: Generic type inference improvements

From Dev

Problems using generics and type inference in Java

From Dev

Confusion over Java generic method type inference

From Dev

Java 8 type inference static method call