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