Typed Method handles
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Thu Jun 9 02:55:50 PDT 2011
Hi all,
What happens if method handles takes variable arty of generic type
parameters.
MethodHandle<void,int> mh = #{x -> System.out.println(x);};
mh.invokeExack(1); //compiles
mh.invokeExack("1"); //compile fail
methodhandle is a special case and can take any number of type parameters
including primitive and reference types.
With this compiler can check types and number of method handle's
invokeExack/invoke invocations.
This only happens if declaration have generic type params.
But how to pass this method handles as method args.
I assume we have following method.
class Test{
static void test(MethodHandle<void,int> mh){
}
}
Now I can pass above methodhandle as following to test method.
Test.test(mh);
But can i overload this method with another method handles that takes
difference form of type parameters.
Currently answer is No.
So type parameters for MethodHandles in parameter declarations have little
benefit and we can does not support that.
Main problem for use of method handles is that they can not be saticaly
checked by compiler for type safety.
I think by specially handling of generic parameters for method handles can
be solved (althogh, not completely).
But what is other solution for passing method handles to other methods as
args. This is SAM types.
by assuming of follwing code:
class Test{
interface SAM{
void m(int x);
}
static void test(SAM sam){
}
}
MethodHandle<void,int> mh = #{x -> System.out.println(x);};
Now can i pass this methodhandle directly to test method.
Test.test(mh);
abvuse answer is No at all. compiler rejects that.
But how to turn of this type checking.
My idea is intruducing of an empty compiler and jvm aware marker interface.
and retrufit all Sam types with it.
interface MHAware{ //Dynamic Or UnCheckedType Or StructurallyCheckable
}
And new version of SAM interface:
interface SAM implements MHAware{
void m(int x);
}
MethodHandle<void,int> mh = #{x -> System.out.println(x);};
Test.test(mh);
This time compiler only checks structural compatibility and does not do any
conversion.
MethodHandle<void,int> <-----> interface SAM implements MHAware{ void
m(int x); }
Therefore for following compile fails.
MethodHandle<void,int,int> mh2 = #{x , y -> System.out.println(x+y);};
Test.test(mh2); //compile error: MethodHandle<void,int> and SAM are not
structurally compatible.
Some Issues:
1) Sam types can be casted to methodhandles. MethodHandle<void,intt> mh =
sam;
..
But invocation on this types must be specialy handled by jvm and treated
them as method handle (original type is MethodHandle);
Alternative solution:
generate a concreate class implementing Sam typea
class SamImp implements Sam,MethodHandleAware{
final MethodHandle<void,int> target;
SamImp(MethodHandle<void,int> mh){ this.target = mh}
MethodHandle<void,int> asMethodHandle(){ return this.target}
void m(int x){ mh.invokeExact(x);}
}
Test.test(new SamImp(mh2));
Final note: My main goal in this post is that lambdas purely implemented by
method handles. And we don't have any overhead of Sam conversions (proxy
objects and reflection).
I think, i walk on clouds.
What do you think?
Best Regards
Ali Ebrahimi
More information about the lambda-dev
mailing list