Method references with types [Re: lambda syntax tutorial]
Peter Levart
peter.levart at marand.si
Fri Aug 6 09:57:36 PDT 2010
While it would be nice if method reference expressions and lambda expressions could be directly convertible to "java.dyn.MethodHandle" and/or "java.lang.reflect.Method" objects, these two target types do not provide for static type-safety, parameter type inference and exception transparency from the language perspective. I don't know what the final compilation strategy is going to be for lambdas and method references, but it was suggested that they both would first be materialized as a MethodHandle and then this MH would be converted to target SAM instance using static method:
MethodHandles.asSam(MethodHandle, Class)
So instead of enabling direct conversion of method reference expressions and lambda expressions to MethodHandles and/or Methods, I propose that the target SAM instance returned from the MethodHandles.asSam method, in addition to implementing/extending the target SAM type, also conditionaly implements the following additional interfaces:
// if converted from a lambda expression ...
public interface MethodHandleReference {
MethodHandle getTargetMethodHandle();
}
// if converted from an unbound method reference expression (i.e. Foo#bar()) ...
public interface MethodReference extends MethodHandleReference {
Method getTargetMethod();
}
// if converted from a bound method reference expression (i.e. someFoo#bar()) ...
public interface BoundMethodReference<T> extends MethodReference {
T getBoundInstance();
MethodHandle getBoundMethodHandle();
}
// if converted from a constructor reference expression (i.e. #new Foo())
public interface ConstructorReference<T> extends MethodHandleReference {
Constructor<T> getTargetConstructor();
}
... these 4 interfaces could be treated in a special way when converting to SAM types. For example, with the following method definition:
public <T extends SamType & MethodReference> doSomething(T sam) { ... }
... one could force the client of such API to only accept a method reference expression compatible with the particular SAM type.
With such scheme you could get both worlds at the same time: static type-safeness and dynamic/reflective access.
Regards, Peter
On 08/06/10, Stephen Colebourne wrote:
> The complete set of conversions would be:
>
> // automatic SAM conversion to instance method from an expression
> str#length()
> assignable to
> interface IntProducer { int get(); }
>
> // automatic SAM conversion to instance method
> String#length()
> assignable to
> interface IntExtractor { int get(String); }
>
> // automatic SAM conversion to static method
> String#valueOf(int)
> assignable to
> interface IntFactory { String get(int); }
>
> // automatic SAM conversion to constructor
> Integer#l(String)
> assignable to
> interface IntegerFactory { Integer get(String); }
>
> // automatic reflected method conversion
> java.lang.reflect.Method m = String#length();
>
> // automatic reflected constructor conversion
> java.lang.reflect.Constructor<Integer> c = Integer#l(String);
>
> // automatic reflected field conversion
> java.lang.reflect.Field f = Person#lsurname;
>
> // automatic invokedynamic conversion
> java.dyn.MethodHandle mh = String#length();
>
>
> as described in FCM https://docs.google.com/Doc?id=ddhp95vd_6hg3qhc
> many moons ago.
>
> Stephen
>
>
>
> On 5 August 2010 22:59, Paul Benedict <pbenedict at apache.org> wrote:
> > // automatic SAM conversion
> > Arrays.sortBy(strings, String#length());
> >
> > // automatic reflected method conversion
> > java.lang.reflect.Method m = String#length();
> >
> > // automatic invokedynamic conversion
> > java.dyn.MethodHandle mh = String#length();
> >
> > Paul
> >
> >
>
>
More information about the lambda-dev
mailing list