Recently I took the time to read the early draft of JSR-292, the invokedynamic bytecode specification. For those slightly less familiar with the subject, it makes it possible to perform late binding on method invocations, allowing for calling methods on objects without knowing the object type at compile time. This feature is important for projects such as Jython and JRuby, which provide Java bytecode compilation to the popular Python and Ruby languages.
Taking a different angle on this feature, it might be useful for the Java language itself and for frameworks developed with it. For example, UI event propagation can be made easier with objects either dealing with the event themselves (by implementing the called method) or passing the call to their container. Another could be an extension to the invokeLater method which takes a target object and the new MethodHandle interface, calling the method directly on the object instead of creating an anonymous class for it, as usually is done. It could also aid frameworks such as MVEL, allowing it to become less complex while maintaining a higher performance value.
In either case, I had a few questions regarding it and just missed the deadline (by merely 4 months!) so I’ll just write them here.
Null references
The draft says that “(there are) no requirements on its receiver argument, except that it be a non-null object reference”. I ask: since the null object is supposed to be a bottom type, why can’t it receive all methods and return a default value (null, 0, false) as a return type?
Awkward syntax
The suggested syntax for the dynamic call is “((Dynamic)x).myMethod(y, z)”, meaning “cast to the empty Dynamic interface, then call the undeclared method”. I can imagine the compiler could use invokevirtual when it can and invokedynamic when it can’t, but then it would remove type-safety entirely.
So, I understand that the guideline behind this awkward syntax is to help the compiler know when to use the invokedynamic bytecode while allowing the developer to specify when it wants it to happen. That said, I still don’t like the casting style. I would prefer a declarative style, such as using annotations, to declare that a specific parameter, variable or field could be used in a dynamic manner, i.e. be invoked using invokedynamic.
For example, the following code, using original syntax:
void someMethod(Object x) { ((Dynamic)a).myMethod(y, z); }
Would look like the following using a declarative annotation:
void someMethod(@Dynamic Object x) { a.myMethod(y, z); }
I’m not suggesting a different operator for dynamic method invocations even though it might be a nice idea; That is because I know that the topic of multiple operators is an extremely loaded one.
Conclusions
All in all, I can’t wait for a feature like JSR-292 to appear in Java. I think that many currently developed frameworks would benefit greatly from creating branches using this feature, and obviously fresh frameworks and next versions of the Java framework itself would as well. As always, I’m interested to hear what you think about this, so please – go ahead! Comment!
P.S. I’ve been getting remarks from people that they couldn’t comment properly. I upgraded the WordPress version and now, hopefully, comments should work. If a comment fails, try again and let me know that it did! Thanks!
December 20th, 2008 at 3:01 am
You don’t want the @Dynamic on the object itself, since you may want a mix of static and dynamic dispatch on the same object. Better to use fan’s syntax of -> for a dynamic call: a->myMethod(y, z).
December 20th, 2008 at 7:27 am
@Lawrence: As I said, I’m for another operator; it was actually my first intuition. But, I just know it’s a difficult subject for some people.