I used to think of references to the java method as syntactic sugar, which was introduced as an addition to lambda expressions. But apparently this is not so.
In the example below, a method reference, unlike a lambda expression, throws an error. Can anyone explain this weird behavior?
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
System.out.println(getMapUsingLanmdaApproach(MyEnum.class));
System.out.println(getMapUsingMethodReferenceApproach(MyEnum.class));
}
static <K, V extends Enum<?> & HasProperty<K>> Map<K, V> getMapUsingLanmdaApproach(Class<V> aClass) {
return Stream.of(aClass.getEnumConstants())
.collect(Collectors.toMap(e -> e.getProperty(), Function.identity()));
}
static <K, V extends Enum<?> & HasProperty<K>> Map<K, V> getMapUsingMethodReferenceApproach(Class<V> aClass) {
return Stream.of(aClass.getEnumConstants())
.collect(Collectors.toMap(HasProperty::getProperty, Function.identity()));
}
}
enum MyEnum implements HasProperty<Integer> {
A(1),
B(2);
private final Integer property;
MyEnum(Integer property) {
this.property = property;
}
@Override
public Integer getProperty() {
return property;
}
}
@FunctionalInterface
interface HasProperty<K> {
K getProperty();
}
Result:
{1=A, 2=B}
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
at Main.getMapUsingMethodReferenceApproach(Main.java:19)
at Main.main(Main.java:10)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Enum; not a subtype of implementation type interface HasProperty
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
... 4 more
I ran the example in the following versions of java:
1.8.0_101-b13
1.8.0_131-B11
source
share