JDK 8 - Lambda - Reflection issues

Remi Forax forax at univ-mlv.fr
Wed Mar 12 18:42:06 UTC 2014


On 03/12/2014 07:12 PM, Pavel Bucek wrote:
> Hello all,
>
> I have an issue with getting generic parameter when using lambdas. I 
> can get the type when using anonymous classes.
>
> code sample will be more descriptive than anything I would say, so.. :
>
> public class Main {
>
>     public static interface A<T> {
>         public void method(T param);
>     }
>
>     public static void main(String[] args) {
>
>         final A<Main> anonClass = new A<Main>() {
>             @Override
>             public void method(Main param) {
>                 System.out.println("234");
>             }
>         };
>
>         final A<Main> lambda = param -> System.out.println("234");
>
>         //following does not help.
>         // final A<Main> lambda = (A<Main>)param -> 
> System.out.println("234");
>
>
>         // output: Main.Main$A<Main>
>         System.out.println("$ " + 
> anonClass.getClass().getGenericInterfaces()[0]);
>
>         // output: interface Main$A          ### generic type info is 
> already lost (no <Main>)
>         System.out.println("# " + 
> lambda.getClass().getGenericInterfaces()[0]);
>
>         // parameterized type from annon class
>         final Type t = 
> ((ParameterizedType)anonClass.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
>         System.out.println("$ " + t);
>
>         // parameterized type from lambda
>         System.out.println("# " + "???");
>     }
> }
>
> I was not able to find any useful documentation or article about this, 
> so sorry if this is something common - feel free to RTM me (with 
> relevant link please).
>
> Thanks and regards,
> Pavel

As you have seen a lambda is not an anonymous class :)

A non-serializable lambda is more lightweight than an anonymous class so 
the generic information that are transmitted from the bytecode to the 
runtime (the lambda metafactory) are not kept inside the lambda class (a 
lambda class may be shared by several different lambdas).

A serializable lambda keep these information because you need them to 
deserialize a lambda but they are not publicly available
The current implementation encoded them in the bytecode and this 
bytecode is not publicly available so unless you serialize the lambda 
and serialize it by hand, you can not have access to these information.

So you can not use a lambda with frameworks like Jackson that use the 
TypeReference idiom,
you can still use an anonymous class for that :)

cheers,
Rémi



More information about the jdk8-dev mailing list