Introduce a compiler option to store generic type information about a lambda expression using the Signature Attribute

Timo Walther twalthr at apache.org
Wed Jan 7 15:22:12 UTC 2015


Hi all,

the Java Reflection API allows to access the generic signature of 
methods through the java.lang.reflect.Method#getGenericReturnType() 
method. However, this is not yet supported for Lambda expressions.

Given the following classes:

class Tuple2<F0,F1> {
   F0 field0;
   F1 field1;

   public Tuple2(F0 f0, F1 f1) {
     this.field0 = f0;
     this.field1 = f1;
   }
}

interface Map<IN, OUT> {
   OUT map(IN in);
}

Currently, there is no solution that allows to get further type 
information about expressions like:

Map<String, Tuple2<String, Integer>> map = (str) -> new Tuple2<>(str, 1);
System.out.println(getReturnType(map)) // can only print Tuple2 => 
information about the Tuple2's fields are always lost

Especially data-intensive runtimes (like Apache Flink[0] where I am 
working on) need as much type information as possible to be efficient. 
Therefore, we searched for a way to also extract type information from 
lambda expressions. Adding a generic signature to the generated 
"lambda$XXX" static methods (at least by using a compiler option) would 
be the perfect solution. It seems that the JVM Specification does not 
prohibit such an implementation. An implementation of a later extraction 
is described here[1].

The Eclipse JDT compiler team is introducing a compiler option 
"-genericsignature" with version 4.5 M4[2].

I have implemented a patch prototype. It can be found at: 
http://people.apache.org/~twalthr/patches/lambdaSignature.patch

The patch postpones the type erasure of the lambda function's parameters 
after the generic descriptor has been saved in a newly introduced 
variable in MethodSymbol (if compiler option "-lambdasignature" is set). 
The contents of the variable is read in ClassWriter and written to 
method's Signature attribute in the classfile. Tests are also included.

No change to the class file format is required. The change is guarded by 
a compiler option, so without that addition, nothing should behave 
differently.


[0] http://flink.apache.org/
[1] 
http://stackoverflow.com/questions/21887358/reflection-type-inference-on-java-8-lambdas
[2] https://bugs.eclipse.org/bugs/show_bug.cgi?id=449063


Regards,
Timo Walther


More information about the compiler-dev mailing list