Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method reference and Generics in Java-8

I am facing issue with method reference combined with generic types.

We have code where we need to call a overloaded method, but it is failing with error:

Cannot resolve value m1()

I have simplified my problem to make it clear where the problem lies.

The following code fails:

public class Test {
    void test() {
        // Getting error here
        setValue(C1::m1, Integer.ONE);
    }

    <E extends I1, T> void setValue(BiConsumer<E, T> cons, T value) {
    }
}

interface I1 {
}

class C1 implements I1 {
    void m1(Integer value) {
    }

    void m1(int value) {
    }
}

Can someone please why this is behaving like this ?

Kindly note this is not related to the question Java 8 Method reference with generic types

like image 816
Sachin Sachdeva Avatar asked Dec 13 '19 08:12

Sachin Sachdeva


Video Answer


1 Answers

It seems that the type inference rules aren't "smart" enough to resolve the conflict between picking the right m1 variant and generating the correct inferred type parameters to the setValue call (B and BigDecimal respectively).

I can't quite explain why this fails, but type inference has traditionally been an area with arcane, well-reasoned and un-intuitive rules, so I'm not very suprised.

You can work around this issue by adding a type witness (specifying which type parameters you want to call setValue with) at which point the compiler will pick the correct m1 method:

this.<B,BigDecimal>setValue(B::m1, BigDecimal.ONE);
like image 79
Joachim Sauer Avatar answered Oct 26 '22 01:10

Joachim Sauer