Lambda with anonymous or local class inside unnecessarily captures 'this'

Tagir Valeev amaembo at gmail.com
Mon Nov 17 16:52:28 UTC 2025


Hello!

Thank you for your replies and for terminology clarification. I've created
an issue based on this discussion:
https://bugs.openjdk.org/browse/JDK-8372010
Feel free to edit it if it's not clearly formulated.

With best regards,
Tagir Valeev

On Sun, Nov 16, 2025 at 7:28 PM Archie Cobbs <archie.cobbs at gmail.com> wrote:

> Hi Chen,
>
> You're right, I had it backwards re: old vs. new behavior. Instead, I'm
> guessing the new (and better) behavior in the
> "withLocalClassInsideNoInstance" case is just a side effect of recent code
> refactorings. Also my speculation that the reason for the capture was due
> to the newly added null check was incorrect; instead, the capture was
> already there before.
>
> So to summarize (correct me if I'm wrong) it should be possible to
> eliminate the capture for local and anonymous classes when the outer
> instance is not actually used, and that would fix both of the remaining
> cases in Tagir's test ("withAnonymousRunnableInside"
> and "withLocalClassInside").
>
> Thanks for clarifying!
>
> -Archie
>
> On Fri, Nov 14, 2025 at 9:15 AM Chen Liang <chen.l.liang at oracle.com>
> wrote:
>
>> The situation in which non-member nested classes capture the enclosing
>> instance unconditionally can be treated as an implementation artifact of
>> javac; we discussed this within Oracle a while ago. The enclosing instance
>> capture being the leading parameter and the null check are for linkage, but
>> local and anonymous classes do not have such linkage links, and it should
>> be JLS-compliant that unused enclosing instance capture is dropped
>> altogether. There are local and anonymous classes in early construction
>> context and static context that don't perform enclosing instance capture,
>> yet reflectively they are not distinguished from the ones that do, so I
>> believe the compatibility impact is low.
>>
>> Re Archie: I think Tagir means that for 23 and below, the lambdas with
>> local or anonymous classes are still captured. It is interesting
>> withLocalClassInsideNoInstance() is suddenly deduplicated.
>>
>> P.S. "Deduplication" is a confusing term - in javac I believe it refers
>> to identical lambda expressions reusing the same InvokeDynamic constant
>> (which still generates different call sites per JVMS rules), but in this
>> thread it refers to the singleton lambda instances.
>>
>>
>
> --
> Archie L. Cobbs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20251117/4b8480be/attachment.htm>


More information about the compiler-dev mailing list