Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Method reference with generic types

I am having issues with Java 8 method reference combined with generic types. I have simplified my problem to make it clear where the problem lies. The following code fails:

public static void main(String[] args) {
    new Mapper(TestEvent::setId);
}

private static class Mapper<T> {
    private BiConsumer<TestEvent, T> setter;
    private Mapper(BiConsumer<TestEvent, T> setter) { this.setter = setter; }
}

private static class TestEvent {
    public void setId(Long id) { }
}

But if I change the constructor invocation to

    BiConsumer<TestEvent, Long> consumer = TestEvent::setId;
    new Mapper(consumer);

Everything works. Can someone explain why?

I know that it works if I remove the generic type (T) and use Long instead, but that will not work when solving my real problem.

like image 426
Johan Frick Avatar asked Mar 28 '14 15:03

Johan Frick


People also ask

What is Java 8 method reference?

Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

Can you use primitive types with generics in Java?

Using generics, primitive types can not be passed as type parameters. In the example given below, if we pass int primitive type to box class, then compiler will complain. To mitigate the same, we need to pass the Integer object instead of int primitive type.


1 Answers

Currently you're trying to use the raw mapper type, which erases all kinds of things.

As soon as you start using the generic type, all is fine - and type inference can help you:

new Mapper<>(TestEvent::setId);

Adding <> is all that's required to make your code compile.

like image 186
Jon Skeet Avatar answered Oct 21 '22 04:10

Jon Skeet