FK~

Moje odkazy

Ostatní odkazy

Close Windows
Nenajdete mě na Facebooku ani Twitteru
Rozpad EU
Jsem členem FSF
There Is No Cloud …just other people's computers.
Sane software manifesto / Manifest příčetného softwaru

Java 8: lambdy, uzávěry a platnost proměnných

vydáno: 5. 9. 2014 11:32, aktualizováno: 7. 9. 2014 18:52

Lexikální uzávěr (closure) je tvořený funkcí a prostředím, ze kterého pochází (proměnné, metody…). Odkaz na funkci můžeme předávat dál a funkce tak putuje naším programem – ale stále má vazbu na kontext, ve kterém vznikla, a může používat jeho proměnné a metody. Ale má to určitá pravidla.

Logo OpenJDK (průhledné 1)

Uvnitř funkce máme k dispozici lokální proměnné, ovšem jen ty, které se nemění – musí být final nebo tzv. efektivně final:

int x = 123;
final int y = 456;
int z = 789;

Function<Integer, Integer> fx = (i) -> i + x; // tohle nejde přeložit
Function<Integer, Integer> fy = (i) -> i + y; // y je (explicitně) final
Function<Integer, Integer> fz = (i) -> i + z; // z je efektivně final
 
x = 666; // důvod, proč x není efektivně final

A sami tyto proměnné taky měnit nemůžeme: např. z++ uvnitř funkce mít nelze.

Pokud vám to přijde příliš omezující, můžete toto pravidlo obejít pomocí referencí (nebo třeba jednoprvkových polí). Reference sice taky musí být (efektivně) final, ale hodnota, na kterou odkazuje se může měnit:

final AtomicReference<Integer> a = new AtomicReference<>(100);
AtomicReference<Integer>       b = new AtomicReference<>(200);

AtomicReference<Integer> počítadlo = new AtomicReference<>(0);

Function<Integer, Integer> fa = i -> {
	počítadlo.getAndUpdate(p -> p + 1); // počítadlo++
	return i + a.get();
};

Function<Integer, Integer> fb = i -> {
	počítadlo.updateAndGet(p -> p + 1); // ++počítadlo
	return i + b.get();
};

// proměnné jako takové jsou final
// jen voláme metody daných objektů, neměníme obsah proměnné
a.set(150);
b.set(250);

Ale moc to nepřehánějte, protože funkce plné vedlejších efektů a funkce, jejichž chování se magicky mění na základě hodnoty okolních proměnných, mohou vést k dost špatně čitelnému kódu.

S členskými proměnnými naší třídy (statickými i instančními) můžeme ve funkcích pracovat stejně jako v anonymních třídách. Rovněž můžeme volat metody naší třídy.

Odkazy a zdroje:

Témata: [Java]

Komentáře čtenářů

Tento článek zatím nikdo nekomentoval

Přidat komentář

reagujete na jiný komentář (zrušit)
jméno nebo přezdívka
název příspěvku
webová stránka, blog
e-mailová adresa
nápověda: možnosti formátování
ochrana proti spamu a špatným trollům

Náhled komentáře