[ Webhosting profitux.cz ]
v6ak [ programování, bezpečnost, web, php, java, ... ] (Vít Šesták)
Buzz - v6ak Twitter - v6ak

štítky

Co je tak úžasného na klíčovém slově final?

Programujete v Javě? Asi znáte klíčové slova final. Že je úžasné? Není? Tak to jej asi neznáte dostatečně dobrě! Pojďte se s ním blíže seznámit.

Final lze použít nejen pro metody a třídy, ale i pro vlastnosti a proměnné. Znamená to zhruba to, že do proměnné musí být hodnota přiřazena právě jednou (až na určité výjimky, které zde nebudu probírat). Tedy:

Že je to málo? Tak to se podívejte na praktické využití.

O parametry konstruktoru se starám až potom

K typickým využitím asi budou patřit vlastnosti tříd, které jsou inicializovány v konstruktoru a poté se nemění. Nejde tedy o žádný okrajový případ. V praxi se to týká nejen neměnných tříd. Co třeba konstruktorová varianta Dependency Injection?

Čemu to pomůže?

Nevím, jak vy, ale já přemýšlím nad parametry konstruktoru často až nakonec. Prostě píšu třídu, uvádím vlastnosti, používám je, ale ještě nemám konstruktor. Jak pak budu vědět, co všechno mám inicializovat? A co když přidávám vlastnosti? To mám pak vždy zkontrolovat, zda všechny vlastnosti inicializuji? Pokud bych je neinicializoval, pak by se to projevilo až za běhu, což není nejpříjemnější varianta!

Není to pravda! Stačí ono kouzelné, pardon, klíčové slovíčko final! Je to velmi jednoduché: před každou proměnnou, kterou máte v úmyslu nastavovat pouze v konstruktoru, uvedete klíčové slovo final. A je to!

Zapomněl jsem inicializovat, co se stane?

To je velmi jednoduché. Prostě to nezkompilujete:
neinicializovaná final vlastnost bez konstruktoru chybové hlášky pro neinicializovanou final vlastnost neinicializovaná final vlastnost s konstruktorem

Neinicializovaná datová složka není null

Abych to ujasnil, je u finálních vlastností zásadní rozdíl mezi neinicializovanou vlastností a hodnotou null. Pokud není inicializovaná, kompilátor se bude bránit použití. Pokud se budete snažit final vlastnosti nastavit null, kompilátor se bránit nebude! Nejde o žádné obejítí. Může nastat situace, kdy chcete, aby byla finální datová složka null. Ale musíte jí takovou hodnotu přiřadit. Pokud si neuvědomujete přesně význam slova final, může být zrádné:

public class Foo { private final int i; private final String bar; public Foo(int i, String bar){ this.i = i; this.bar = bar; // bar může být i null, což programátor možná nechtěl } }

Stručně řečeno, nezaměňujte final s dynamickou kontrolou, zda se proměnná nerovná null.

Využití klíčového slova final v anonymních třídách

Anonymní třídu můžete vytvořit uvnitř nějaké metody. Má přístup ke všem vlastnostem, ke kterým má přístup vnější metoda:

public class IncrementRunnableFactory { private final AtomicInteger count = new AtomicInteger(); public Runnable createRunnable(){ return new Runnable(){@Override public void run() { count.incrementAndGet(); }}; } }

To může být zároveň zradou, pokud by třída IncrementRunnableFactory mohla zaniknout dříve než vrácená Runnable. Zde to není problém - bez ní by vrácená instance Runnable neměla smysl.

Nicméně, zkusíme příklad trošku upravit. Řekněme, že budeme chtít přičíst více. A to podle parametru. Ale to už nefunguje:
Pokus o přístup k non-final proměnné

Proč? Ve chvíli, kdy se vykonává metoda run(), už nemusí existovat proměnná add. Co s tím? Překvapivě - final. Tím řeknete kompilátoru, že se proměnná add nebude měnit. A co na to kompilátor? Patrně ji zkopíruje. (Neznám implementační detaily, ale jak jinak to chcete udělat?) Je to jednoduché řešení, jak přidat anonymní třídě nějaký kontext, de facto parametry:

import java.util.concurrent.atomic.AtomicInteger; public class IncrementRunnableFactory { private final AtomicInteger count = new AtomicInteger(); public Runnable createRunnable(final int add){ return new Runnable(){@Override public void run() { count.addAndGet(add); }}; } }

Jak vidíte, funguje to i pro parametry. Úplně stejně to funguje pro proměnné metod.

Musíte si ale dát pozor, možná tím můžete umělě prodloužit životnost ostatních final proměnných (nevyzkoušeno).

To je hezké, ale jak mám vědět, že zavedením klíčových slov final do stávajícího kódu nic nepokazím?

Pokud si nejste jisti, zda bude kód funkční i po přidání final, prostě to zkuste. Pokud ne, kompilátor vy měl vyhlásit chybu. A pokud ji vyhlásí, jsou tu asi tyto možnosti:

Diskuzi ke článku naleznete zde.

Linkování

Líbí se Vám tato stránka? Zalinkujte ji!

Chcete sledovat novinky? Pokud si právě prohlížíte článek a hledáte RSS pro celý web, pak jste trošku jinde. Možná hledáte poslední změny.

Validní HTML 4.01 StrictValidní CSS 2.0Validní hlavní RSS kanálPHP 5Apache
referer: UA:CCBot/2.0 (http://commoncrawl.org/faq/) time:0.97417700 1503523099
web
mail
comment