import java.lang.invoke.*; import java.util.Arrays; import java.util.List; class Main { void foo() throws Exception { MethodHandles.Lookup l = MethodHandles.lookup(); l.findSpecial(A.class, "foo", MethodType.methodType(void.class), A.class); l.findSpecial(A.class, "foo", MethodType.methodType(void.class), B.class); l.findSpecial(A.class, "foo", MethodType.methodType(void.class), C.class); l.findSpecial(B.class, "foo", MethodType.methodType(void.class), A.class); l.findSpecial(B.class, "foo", MethodType.methodType(void.class), B.class); l.findSpecial(B.class, "foo", MethodType.methodType(void.class), C.class); l.findSpecial(C.class, "foo", MethodType.methodType(void.class), A.class); l.findSpecial(C.class, "foo", MethodType.methodType(void.class), B.class); l.findSpecial(C.class, "foo", MethodType.methodType(void.class), C.class); l.findSpecial(A.class, "foo", MethodType.methodType(double.class), A.class); l.findSpecial(A.class, "bar", MethodType.methodType(int.class), A.class); l.findSpecial(A.class, "bar", MethodType.methodType(int.class), B.class); l.findSpecial(A.class, "bar", MethodType.methodType(int.class), C.class); l.findSpecial(B.class, "bar", MethodType.methodType(int.class), A.class); l.findSpecial(B.class, "bar", MethodType.methodType(int.class), B.class); l.findSpecial(B.class, "bar", MethodType.methodType(int.class), C.class); l.findSpecial(C.class, "bar", MethodType.methodType(int.class), A.class); l.findSpecial(C.class, "bar", MethodType.methodType(int.class), B.class); l.findSpecial(C.class, "bar", MethodType.methodType(int.class), C.class); l.findSpecial(A.class, "bar", MethodType.methodType(double.class), A.class); l.findSpecial(A.class, "baz", MethodType.methodType(String.class, int.class), A.class); l.findSpecial(A.class, "baz", MethodType.methodType(String.class, int.class), B.class); l.findSpecial(A.class, "baz", MethodType.methodType(String.class, int.class), C.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, int.class), A.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, int.class), B.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, int.class), C.class); l.findSpecial(C.class, "baz", MethodType.methodType(String.class, int.class), A.class); l.findSpecial(C.class, "baz", MethodType.methodType(String.class, int.class), B.class); l.findSpecial(C.class, "baz", MethodType.methodType(String.class, int.class), C.class); l.findSpecial(A.class, "baz", MethodType.methodType(String.class, double.class), A.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, double.class), A.class); } void differentMethodTypeOverloads() throws Exception { MethodHandles.Lookup l = MethodHandles.lookup(); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, double.class), C.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, List.of(double.class)), C.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, Arrays.asList(double.class)), C.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, new Class[]{double.class}), C.class); l.findSpecial(B.class, "baz", MethodType.methodType(String.class, MethodType.methodType(void.class, new Class[]{double.class})), C.class); } } interface A { void foo(); default int bar() {return 1;} } abstract class B implements A { public void foo() {} public int bar() {return 2;} abstract String baz(int n); } class C extends B { public void foo() {} public int bar() {return 3;} String baz(int n) {return "" + n;} }