I have two classes A and B, both define method foo() with common signature (accept nothing, return void). They don't have the common base class (or interface) that declares this method. I want to call this method on regardless As or Bs as long as they can respond to this call. This approach is called Duck Typing.
I know that there's an instruction called invokedynamic:
Each instance of an invokedynamic instruction is called a dynamic call site. A dynamic call site is originally in an unlinked state, which means that there is no method specified for the call site to invoke. As previously mentioned, a dynamic call site is linked to a method by means of a bootstrap method. A dynamic call site's bootstrap method is a method specified by the compiler for the dynamically-typed language that is called once by the JVM to link the site. The object returned from the bootstrap method permanently determines the call site's behavior.
So I tried to achive this using MethodHandles. Here's the example:
public static class A {
public void foo() {
}
}
public static class B {
public void foo() {
}
}
public static void main(String[] args) throws Throwable {
final MethodHandle foo = MethodHandles.lookup()
.findVirtual(A.class, "foo", MethodType.methodType(void.class));
foo.invoke(new B());
}
Of course, I've got:
Exception in thread "main" java.lang.ClassCastException: Cannot cast Main$B to Main$A
at sun.invoke.util.ValueConversions.newClassCastException(ValueConversions.java:461)
at sun.invoke.util.ValueConversions.castReference(ValueConversions.java:456)
at Main.main(Main.java:30)
I clearly see the difference between invokedynamic and MethodHanle. I see that the problem is that the foo MethodHandle is bound to the class A, not class B. But is it possible for me to somehow take advantage of invokedynamic in this particular case?
Why do I need this? This is the part of my small research project. I'm trying to understand method handles in depth and I want to call common methods on annotation instances retrieved from fields and methods. I am unable to define base class for annotations in Java, so instead of chain of instanceof's and class casts or retrieving these values using reflection violating access rights, I want to implement this duck typing if possible.
Thanks.


invokedynamicor anything, you need an instance of the correct class to call instance methods. Of course you can't callAmethods onBobjects asAimplementation offoo()may depend on fields / data / private function only present inA.invokedynamicneeds an instance too. On static methods you can passnullas thethisparameters toinvoke, but really: duck typing only works if you already have an instance of the object, which you are missing atm :) – roookeee Jun 11 at 11:04