7

Unlike anonymous inner classes, Java 8 lambdas don't hold references to the enclosing (parent) class. Android N adds support for lambdas.

However, they are implemented in the Jack compiler using anonymous inner classes for backward compatibility, as the note in the link states.

Does this mean that lambdas in Android classes compiled using Jack (and not retrolambda) will hold references to the enclosing class?

I know that one reason many people were excited about lambdas is to avoid Fragment or Activity leaks when using them, but at a cursory glance, it looks like using jack compiler will not give that benefit.

Rohan Dhruva
  • 1,194
  • 1
  • 10
  • 20
  • 1
    Possible duplicate of [Do Java8 lambdas maintain a reference to their enclosing instance like anonymous classes?](http://stackoverflow.com/questions/28446626/do-java8-lambdas-maintain-a-reference-to-their-enclosing-instance-like-anonymous) – Andre Classen Mar 28 '16 at 21:24
  • 1
    @AndreClassen, that question doesn't cover Jack, but you're right, it could be a dupe if retrolambda also decompiles lambdas to anonymous inner classes at the bytecode level. – Rohan Dhruva Mar 28 '16 at 21:49
  • Btw, your assumption that Java 8 lambdas never hold a reference to the enclosing instance is wrong - they of course do if they have to capture instance variables. – Stefan Zobel Mar 29 '16 at 18:52
  • @StefanZobel, yes, that's right, didn't think of that because I was mostly thinking about the android paradigm of creating anonymous inner class listeners which hold reference to the fragment or activity if not cleared and cause memory leaks. my bad. – Rohan Dhruva Mar 29 '16 at 21:44

1 Answers1

5

I think the phrase "anonymous class" shouldn't be interpreted too literally here. In my understanding, the only thing they want to tell us is that Jack generates the classes at compile time (as opposed to the runtime approach of Java 8).

From the JackIrBuilder code I'd guess that the generated IR looks very similar to the bytecode that would be generated by retrolambda.

Jack seems to create a synthetic method containing the lambda body in the enclosing type and passes the reference of the enclosing instance to the generated class' constructor only in those cases where it is needed, i.e. when members of the enclosing instance are captured.

Reference: https://android.googlesource.com/toolchain/jack/+/0af676c4779c5b55fb321f491811516f3d74ed93/jack/src/com/android/jack/ir/impl/JackIrBuilder.java

So, from what I understand, the answer is: only when something needs to be captured from the enclosing instance.

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38