Następująca klasa zawiera zmienną składową runnable
, która jest inicjowana przy użyciu instancji anonimowej klasy wewnętrznej. Wewnętrzna grupa odwołuje się do tego samego członu:Dlaczego lambdas w Javie 8 nie zezwala na przekierowanie do zmiennych składowych, w których klasy anonimowe nie są używane?
class Example {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(runnable);
}
};
}
nie jest problemem jeśli metoda ta nie jest wykonywana zanim element został przypisany, a na trasę umożliwia takie odniesienie.
Oświadczenie o zmiennej składowej teoretycznie może być przekształcany do ekspresji lambda tak:
Runnable runnable =() -> System.out.println(runnable);
moim rozumieniu jest funkcjonalnie równoważny do poprzedniego przykładu, lecz jest odrzucana przez javac 1.8.0_05
z następujących komunikat o błędzie:
Error:(2, 54) java: self-reference in initializer
Chociaż to stwierdzenie jest prawdziwe, nie widzę powodu, dla którego było to zabronione. Czy zostało to celowo zabronione, może dlatego, że wyrażenia lambda są kompilowane do różnych kodów bajtowych, które mogłyby prowadzić do problemów, gdyby było dozwolone? Czy po prostu został odrzucony, ponieważ były już problemy z tymi odniesieniami, gdy były używane w anonimowych klasach wewnętrznych? A może było to niechcący zabronione przez pisarzy JLS? Czy jest to błąd w javac
?
W czasie zaćmienia działa: 'Runnable runnable =() -> System.out.println (this.runnable); 'Zawodzi tylko bez dodanego kwalifikatora' this'. –