2016-03-28 9 views
6

W przeciwieństwie do anonimowych klas wewnętrznych, lambda w języku Java 8 nie zawiera odniesień do klasy otaczającej (rodzica). Android N adds support dla lambdas.Czy lambdas w kompilatorze z systemem Android N ma referencje do klasy?

Są one jednak implementowane w kompilatorze Jack przy użyciu anonimowych klas wewnętrznych w celu zapewnienia kompatybilności wstecznej, co stanowi notatka w stanach łącza.

Czy to oznacza, że ​​lambdy w klasach Androida skompilowane przy użyciu Jacka (a nie retrolambdy) będą zawierały odniesienia do klasy otaczającej?

wiem, że jedną z przyczyn wielu ludzi podekscytowany lambdas jest uniknięcie Fragment lub Activity przecieki podczas korzystania z nich, ale w pobieżnym skrócie, wygląda na to, używając jack kompilator nie da tego świadczenia.

+1

Możliwy duplikat [Czy Javad lambdas zachowuje odwołanie do ich otaczającej instancji, takiej jak anonimowe klasy?] (Http://stackoverflow.com/questions/28446626/do-java8-lambdas-maintain-a-reference-to-their -włączając-przykład-jak-anonimowy) –

+1

@AndreClassen, to pytanie nie dotyczy Jacka, ale masz rację, może to być dupe, jeśli retrolambda dekompiluje lambdy do anonimowych klas wewnętrznych na poziomie bajtodu. –

+0

Przy okazji, twoje założenie, że Java 8 lambdy nigdy nie ma odniesienia do otaczającej instancji, jest błędne - one oczywiście robią, jeśli muszą przechwytywać zmienne instancji. –

Odpowiedz

5

Myślę, że wyrażenie "klasa anonimowa" nie powinno być interpretowane zbyt dosłownie. W moim rozumieniu, jedyną rzeczą, którą chcą nam powiedzieć, jest to, że Jack generuje klasy w czasie kompilacji (w przeciwieństwie do podejścia Java w środowisku wykonawczym 8).

Z kodu JackIrBuilder Zgaduję, że wygenerowane IR wygląda bardzo podobnie do kodu bajtowego, który byłby generowany przez retrolambdę.

Jack wydaje się tworzyć syntetyczną metodę zawierającą ciało lambda w typie otaczającym i przekazuje odwołanie do instancji zamykającej do konstruktora generowanej klasy tylko w tych przypadkach, w których jest to potrzebne, tj. Gdy członkowie enlosing instance są schwytany.

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

Tak, z tego co rozumiem, to odpowiedź brzmi: tylko kiedy musi coś być zrobione z instancji osłaniającego.