Run the following code:
import java.util.List;
public class Test {
public static void main(String[] args) {
System.out.println("Testing with explicit type");
MyGroup group = new MyGroup();
System.out.println(" Testing lambda");
if (group.getPersons().stream().anyMatch(p -> p.isFoo())) {}
System.out.println(" Lambda is good");
System.out.println(" Testing method reference");
if (group.getPersons().stream().anyMatch(Test.Person::isFoo)) {}
System.out.println(" Method reference is good");
System.out.println("Testing with wildcard");
Group<?> group2 = new MyGroup();
System.out.println(" Testing lambda");
if (group2.getPersons().stream().anyMatch(p -> p.isFoo())) {}
System.out.println(" Lambda is good");
System.out.println(" Testing method reference");
if (group2.getPersons().stream().anyMatch(Test.Person::isFoo)) {}
System.out.println(" Method reference is good");
}
interface Group<T extends Person> {
List<T> getPersons();
}
interface Person {
boolean isFoo();
}
static class MyGroup implements Group<MyPerson> {
@Override
public List<MyPerson> getPersons() {
return List.of();
}
}
static class MyPerson implements Person {
@Override
public boolean isFoo() {
return true;
}
}
}
It will fail when using a method reference in combination with the parametrized type:
Testing explicit type
Testing lambda
Lambda is good
Testing method reference
Method reference is good
Testing with wildcard
Testing lambda
Lambda is good
Testing method reference
Exception in thread "main" java.lang.BootstrapMethodError: bootstrap method initialization exception
at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:185)
at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:315)
at java.base/java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:281)
at java.base/java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:271)
at Test.main(Test.java:25)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Object; not a subtype of implementation type interface Test$Person
at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:268)
at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:327)
at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:127)
... 4 more
openjdk version "16" 2021-03-16
OpenJDK Runtime Environment (build 16+36-2231)
OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
import java.util.List;
public class Test {
public static void main(String[] args) {
System.out.println("Testing with explicit type");
MyGroup group = new MyGroup();
System.out.println(" Testing lambda");
if (group.getPersons().stream().anyMatch(p -> p.isFoo())) {}
System.out.println(" Lambda is good");
System.out.println(" Testing method reference");
if (group.getPersons().stream().anyMatch(Test.Person::isFoo)) {}
System.out.println(" Method reference is good");
System.out.println("Testing with wildcard");
Group<?> group2 = new MyGroup();
System.out.println(" Testing lambda");
if (group2.getPersons().stream().anyMatch(p -> p.isFoo())) {}
System.out.println(" Lambda is good");
System.out.println(" Testing method reference");
if (group2.getPersons().stream().anyMatch(Test.Person::isFoo)) {}
System.out.println(" Method reference is good");
}
interface Group<T extends Person> {
List<T> getPersons();
}
interface Person {
boolean isFoo();
}
static class MyGroup implements Group<MyPerson> {
@Override
public List<MyPerson> getPersons() {
return List.of();
}
}
static class MyPerson implements Person {
@Override
public boolean isFoo() {
return true;
}
}
}
It will fail when using a method reference in combination with the parametrized type:
Testing explicit type
Testing lambda
Lambda is good
Testing method reference
Method reference is good
Testing with wildcard
Testing lambda
Lambda is good
Testing method reference
Exception in thread "main" java.lang.BootstrapMethodError: bootstrap method initialization exception
at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:185)
at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:315)
at java.base/java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:281)
at java.base/java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:271)
at Test.main(Test.java:25)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Object; not a subtype of implementation type interface Test$Person
at java.base/java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:268)
at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:327)
at java.base/java.lang.invoke.BootstrapMethodInvoker.invoke(BootstrapMethodInvoker.java:127)
... 4 more
openjdk version "16" 2021-03-16
OpenJDK Runtime Environment (build 16+36-2231)
OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
- relates to
-
JDK-8141508 java.lang.invoke.LambdaConversionException: Invalid receiver type ...
-
- Closed
-