Próbuję zmienić ten kod, aby użyć lambda zamiast anonimowej klasy. Jest to prosta lista elementów w GUI. Rejestruję innego słuchacza dla każdego przedmiotu, a ostatni utworzony element robi coś specjalnego po kliknięciu.Kod zachowuje się inaczej po konwersji klasy anonimowej na lambda
class ItemList {
interface OnClickListener {
void onClick();
}
OnClickListener current;
OnClickListener newListener(final int n) {
return current = new OnClickListener() {
public void onClick() {
if (this == current)
System.out.println("doing something special (item #"+n+")");
System.out.println("selected item #" + n);
}
};
}
public static void main(String[] args) {
ItemList l = new ItemList();
OnClickListener ocl1 = l.newListener(1);
OnClickListener ocl2 = l.newListener(2);
OnClickListener ocl3 = l.newListener(3);
ocl1.onClick();
ocl2.onClick();
ocl3.onClick();
}
}
To działa zgodnie z oczekiwaniami:
$ javac ItemList.java && java ItemList
selected item #1
selected item #2
doing something special (item #3)
selected item #3
Teraz mogę zmienić go użyć lambda zamiast anonimowego klasy:
class ItemList {
interface OnClickListener {
void onClick();
}
OnClickListener current;
OnClickListener newListener(final int n) {
return current =() -> {
if (this == current)
System.out.println("doing something special (item #"+n+")");
System.out.println("selected item #" + n);
};
}
public static void main(String[] args) {
ItemList l = new ItemList();
OnClickListener ocl1 = l.newListener(1);
OnClickListener ocl2 = l.newListener(2);
OnClickListener ocl3 = l.newListener(3);
ocl1.onClick();
ocl2.onClick();
ocl3.onClick();
}
}
Ale teraz to już nie robi nic szczególnego na ostatni pozycja? Czemu? Czy ==
działa inaczej w lambdach? Myślałem, że to był błąd w retrolambdzie na początku, ale ten przykład działa na zwykłym JDK8 i nadal się dzieje.
$ javac A.java && java A
selected item #1
selected item #2
selected item #3
Lambda naprawdę nie może odnosić się do "tego" w ich ciele. –