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