Lambda and JSR 292 method handle
Howard Lovatt
howard.lovatt at iee.org
Fri Dec 18 02:55:52 PST 2009
Rémi,
I thought the idea from the JSR 292 group was to use JavaMethodHandle
[1] (which extends MethodHandle). The difference is that the
JavaMethodHandle retains the type information, needed by Java, and it
can implement interfaces so you can use a lambda with an existing
function. Your example:
class A {
public static void main(String[] args) {
#int(int) f = #(int x) (x+x);
f(2);
}
}
Would get translated to:
class A {
private static final class Lambda$1 extends JavaMethodHandle
implements CallableIntInt {
private static final Lambda$1 instance = new Lambda$1();
@Override public int call( int x ) { return x + x; }
private Lambda$1() { super "CALL"; }
private static final MethodHandle CALL =
MethodHandles.lookup().findVirtual( Lambda$1.class, "call",
MethodHandles.methodType( int.class, int.class ) );
}
public static void main(String[] args) {
CallableIntInt f = Lambda$1.instance;
f.call(2);
}
}
Where CallableIntInt is either a standard interface, in java.lang say,
or a synthetic interface (depending on implementation details) and is:
public interface CallableIntInt { int call( int a ); }
If you use a MethodHandle directly then you can't pass it to anything
because you have lost the type information, i.e. an invokeGeneric on a
method handle will accept any arguments (though will throw a runtime
exception). EG if I have a method:
void m( #int(int) f ) { out.println( f( 2 ) ); }
Then if you use MethodHandles directly it would be translated to:
void m( MethodHandle f ) { out.println( f.<int>invokeGeneric( 2 ) ); }
But then I could say:
m( #void() () );
And the compiler couldn't catch the mistake. Using JavaMethodHandles
instead, would mean m is translated into:
void m( CallableIntInt f ) { out.println( f.call( 2 ) ); }
And hence retains type safety.
The above JavaMethodHandle version doesn't seem to be that much better
than using an inner class directly! There was also, at least
originally, talk of anonymous classes in JSR 292 [2]; these would seem
to be more useful, are they still part of JSR 292? (I ask because I
think you are on the expert group.)
-- Howard.
PS The above APIs are in a state of flux, I have used the versions (at
least I tried to without having a compiler to check my code) from the
paper you can download from [3].
Ref:
[1] http://cr.openjdk.java.net/~jrose/pres/indy-javadoc-b59/
[2] http://blogs.sun.com/jrose/resource/DVMTest.java.txt
[3] http://blogs.sun.com/jrose/entry/vmil_paper_on_invokedynamic
More information about the lambda-dev
mailing list