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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With