Annotating lambda expressions

Remi Forax forax at
Sat Jul 11 09:26:11 UTC 2015

On 07/11/2015 10:57 AM, Ron Pressler wrote:
> That's a very nice idea (in fact, we can do foo((@Special Runnable) 
> ()->{...}), as well and get ASM to invoke a nice  visitInsnAnnotation 
> event), but it doesn't help, as I have no way of finding the method 
> implementing the lambda by analyzing the bytecode.

The method corresponding to the body of the lambda is one arguments of 
the bootstrap method of invokedynamic.
(this translation scheme is not required to be used by compilers but in 
practice javac and ecj uses it and scalac will use it too)

> My suggestion says, "however the compiler chooses to represent the 
> lambda, please apply the annotation to the implementing method, 
> wherever it is". I think that the language spec at least implicitly 
> forces the compiler to implement a lambda as a method /somewhere/ (as 
> opposed to, say, javac inlining the expression, as Kotlin does with 
> inline functions).

see above.

> The ability to attach introspectable metadata to a lambda expression 
> that then travels with it to the implementing method -- wherever the 
> compiler may choose to place it -- is extremely useful, and trumps, 
> IMO, "purity" concerns re annotating expressions vs declarations, 
> (esp. since we've already established that some expressions -- like 
> cast and new -- are annotatable, and rightly so).

cast and new are not annotatable, the type of a cast or a new are.

> Without this, we miss something important Java gives us, which is the 
> ability to attach metadata to a method body. I fully understand the 
> distinction that the annotation is applied to the /declaration/ rather 
> than the body itself, but that doesn't take away from the fact that a 
> useful ability does not transfer to lambdas while it could be easily done.
> Ron


> On Sat, Jul 11, 2015 at 10:38 AM, Remi Forax <forax at 
> <mailto:forax at>> wrote:
>     On 07/10/2015 11:41 PM, Ron Pressler wrote:
>>     I see no problem with cast annotations not being retrievable via
>>     straightforward reflection just as I see no problem annotating
>>     the generated method (which should always exist /somewhere/): in
>>     both cases, those annotations are intended for use by tools that
>>     analyze the entire project's source/bytecode (e.g. for
>>     typechecking/instrumentation) rather than by specific reflective
>>     queries.
>>     What bothers me is that a capability that was trivial with inner
>>     classes is now lost when using lambdas.
>     you can easily add a pattern recognizable by source/bytecode tools
>     to do what you want,
>     let suppose you have a static method like this:
>       static <T> T annotate(Class<? extends Annotation> annotation, T
>     lambda) { return lambda; }
>     to annotate a lambda, your example can be written like this:
>       foo(annotate(Special.class, () -> { ...}))
>     in the bytecode it will be translated to something like this:
>       ldc Special.class
>       invokedynamic ()Runnable
>         LambdaMetafactory  + method handle ref on the lambda body
>       invokestatic Bar.annotate(Class, Object)Object
>       checkcast Runnable
>       invokevirtual
>     which is easy to recognize.
>>     Ron Pressler
>> <>
>>     @puniverseco <> on Twitter
>     Rémi
>>     On Fri, Jul 10, 2015 at 10:38 PM, Alex Buckley
>>     <alex.buckley at <mailto:alex.buckley at>> wrote:
>>         On 7/10/2015 2:31 AM, Maurizio Cimadamore wrote:
>>             On 10/07/15 09:43, Ron Pressler wrote:
>>                 (Related to
>>                 It is useful to add an annotation to a lambda
>>                 expression -- as in
>>                 foo(@Special () -> { ...}) -- which will be applied
>>                 to the static
>>                 method implementing the lambda (not to the interface
>>                 the lambda
>>                 implements). This would allow instrumentation tools
>>                 operating on
>>                 method implementations to handle lambdas. So far,
>>                 AFAICT, this is not
>>                 possible (or am I wrong?).
>>             This is not possible, currently - as Remi said; you have
>>             annotations on
>>             declarations (i.e. variable, classes, methods) - you have
>>             annotation on
>>             types (i.e. type of a cast, type argument, etc.) - but
>>             you don't have
>>             annotations on _expressions_.
>>             I take it that, under the current translation scheme,
>>             there seems to be
>>             a plausible description for what should happen when the
>>             lambda is
>>             annotated; but what if the lambda is turned into a method
>>             reference (by
>>             some IDE refactoring, or human intervention) ? In that
>>             case it is not
>>             guaranteed that there would still be a physical place
>>             where to put the
>>             annotation (unless we tell the compiler to 'expand' all
>>             annotated method
>>             references).
>>         Yes, the problem with annotations-on-expressions is not the
>>         language grammar but the storage of the annotations in the
>>         class file. With no standard way of translating source
>>         expressions to bytecode, there can be no standard API for
>>         retrieving annotations-on-expressions from bytecode. More
>>         broadly, there has never been a standard reflective API
>>         capable of inspecting method bodies.
>>         This explains why JSR 308 stayed away from
>>         annotations-on-expressions -- we were not in a position to
>>         let them be read back. It was already bad enough that some
>>         annotations-on-types are stored in the class file at the
>>         level of individual bytecodes (e.g. an annotation on the type
>>         of a cast) so are not retrievable by any standard reflective API.
>>         Alex

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the compiler-dev mailing list