Lambda expression as a succinct way to pass in type parameter

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Nov 14 10:16:02 PST 2011


On 14/11/11 17:47, Rémi Forax wrote:
> On 11/14/2011 06:29 PM, Zhong Yu wrote:
>> Hi Brian, I think I have an interesting use case, but I need your
>> confirming that it's viable. Consider a method
>>
>>       <T>   T foo() {...}
>>
>> Suppose the body of foo() needs to know the runtime value of T, due to
>> erasure, we must pass in a construct containing the value of T
>>
>>       <T>   T foo(TypeToken<T>   type) {...}
>>
>>       interface TypeToken<T>
>>       {
>>           int f(int x); // not really used
>>       }
>>
>> We can call foo() this way
>>
>>       Bar result = foo(x->x);
>>
>> The lambda expression x->x is compiled into an object of
>> TypeToken<Bar>, and the body of foo() can use reflection to retrieve
>> T=Bar.
>>
>>       // equivalent code
>>       Bar result = foo(type);
>>
>>       static TypeToken<Bar>   type = new TypeToken<Bar>(){ public int
>> f(int x){ return x; } }
>>
>> Question: do you see anything wrong with this usage pattern? (other
>> than how odd it looks)
>>
>> cheers,
>> Zhong Yu
>>
> Interesting pattern but ...
>
> This may not work because at runtime the reflection will return a class
> that doesn't implements TypeToken<Bar>  but TypeToken
> because a lambda implementation may try to reuse the same class for
> several TypeToken.
>
> The idea is that the class that implements TypeToken will not be
> generated by the compiler
> but by the VM at runtime to avoid to generate boilerplate bytecodes on disc
> so the generation will occur after the erasure so Bar information will
> be lost.
>
> Rémi
>
>
Type-token solutions usually have a common pitfall - they work quite 
well for stuff like:

TypeToken<Bar>

but not so well for:

TypeToken<Foo<Bar>>

I might be wrong - but it does seems to me that this one is no exception.

Maurizio


More information about the lambda-dev mailing list