Lambda containing anonymous or local class unnecessarily captures outer 'this' instance

XMLWordPrintable

    • Type: Bug
    • Resolution: Unresolved
    • Priority: P4
    • 27
    • Affects Version/s: 25
    • Component/s: tools
    • None

      Consider the following class:

      final class CapturingLambda {
          Runnable withAnonymousRunnableInside() {
              return () -> {
                  Runnable r = new Runnable() {
                      @Override
                      public void run() {
                      }
                  };
                  r.run();
              };
          }

          Runnable withLocalClassInside() {
              return () -> {
                  class Local {}
                  new Local();
              };
          }
      }

      The lambdas here are not using the instance of an outer CapturingLambda object, so I expect that they should not capture it. However, this is not the case. Lambda synthetic methods are non-static, and CapturingLambda this object is passed to invokedynamic:

               0: aload_0
               1: invokedynamic #7, 0 // InvokeDynamic #0:run:(LCapturingLambda;)Ljava/lang/Runnable;

      This prevents from creating a singleton lambda instance and unnecessarily keeps the strong reference to an outer object. I think this could be fixed.

      discussed in compiler-dev: https://mail.openjdk.org/pipermail/compiler-dev/2025-November/032133.html

            Assignee:
            Unassigned
            Reporter:
            Tagir Valeev
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: