Lambda expression as a succinct way to pass in type parameter

Zhong Yu zhong.j.yu at gmail.com
Mon Nov 14 18:19:45 PST 2011


On Mon, Nov 14, 2011 at 5:48 PM, Dan Smith <daniel.smith at oracle.com> wrote:
> On Nov 14, 2011, at 11:57 AM, Zhong Yu wrote:
>
>> Suppose a method parameter type is a SAM interface, we must then
>> document whether a lambda expression argument is acceptable. That
>> depends on how the method uses the argument. If the method does
>> nothing but invoking the single abstract method, obviously lambda
>> expression is acceptable. But beyond that, what kinds of usages of the
>> argument makes lambda expression unacceptable? Where's the line that
>> differentiate lambda expressions from "classical" objects?
>
> There's nothing magic about the lambda class's implementation -- it's a perfectly normal class, requiring no special treatment from the VM.  It's just that the class that you get isn't quite what you're expecting.
>
> What you want:
>
> class LambdaImpl implements TypeToken<Bar> { ... }
>
> What you get:
>
> class LambdaImpl<T> implements TypeToken<T> { ... }
>
> or maybe
>
> class LambdaImpl implements TypeToken /*raw*/ { ... }
>
> To give a sense of exactly what implementations are required to do (and what aspects of the class are unspecified), I expect the language specification to ultimately include a section saying something like "the class of which the lambda expression's value is an instance has the following properties: ..."

Well, who has the time to read the spec...

Is the overhead of a new class really so high that such optimization
is justified?

> FWIW, if you don't mind being explicit about the type, but you're not satisfied with what you get from ".class" (no generics, etc.), you could always use an anonymous inner class:
>
> foo(new TypeToken<List<String>>(){});

Of course it's just too repetitive:

    List<String> ls = foo(new TypeToken<List<String>(){});

It gets worse if we want to avoid creating a new object for each call,

    List<String> ls = foo(TYPE);
    static final TypeToken<List<String>> TYPE = new TypeToken<List<String>(){};

This is really unfortunate. I've witnessed many questions on
stackoverflow.com that can be traced to the lack of type literal in
Java. It has significant amount of use cases.

(Actually if all types are reified, many of the problems can be solved
without needing type literal; in our example, it would be nice to
simply write `List<String> ls=foo();` But that's out of discussion
because I assume there is zero chance to ever take erasure out of
Java.)

</whine>
Zhong Yu

> abstract class TypeToken<T> {
>  public Type asReflectType() {
>    return ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
>  }
> }
>
> (Obviously not as elegant as something like 'List<String>.type' would be.)
>
> —Dan
>
>


More information about the lambda-dev mailing list