„Konečné“ kľúčové slovo v jazyku Java

1. Prehľad

Zatiaľ čo dedičstvo nám umožňuje opätovne použiť existujúci kód, niekedy to potrebujeme stanoviť obmedzenia rozšíriteľnosti z rôznych dôvodov; the konečné kľúčové slovo nám umožňuje presne to urobiť.

V tomto výučbe sa pozrieme na to, čo konečné prostriedky pre kľúčové slová pre triedy, metódy a premenné.

2. Konečné Triedy

Triedy označené ako konečné sa nedá predĺžiť. Ak sa pozrieme na kód základných knižníc Java, nájdeme ich veľa konečné triedy tam. Jedným z príkladov je String trieda.

Zvážte situáciu, ak môžeme predĺžiť String triedy, prepísať ktorúkoľvek z jej metód a nahradiť všetky String inštancie s inštanciami našej konkrétnej String podtrieda.

Výsledok operácií viac ako String objekty sa potom stanú nepredvídateľnými. A vzhľadom na to String triedy sa používa všade, je to neprijateľné. Preto String trieda je označená ako konečné.

Akýkoľvek pokus o dedenie z a konečné triedy spôsobí chybu kompilátora. Aby sme to demonštrovali, vytvorme konečné trieda Kat:

verejná finálna trieda Cat {private int váha; // štandardný getter a setter}

Skúsme to predĺžiť:

verejná trieda BlackCat rozširuje Cat {}

Uvidíme chybu kompilátora:

Typ BlackCat nemôže byť podtriedou finálnej triedy Cat

Poznač si to the konečné kľúčové slovo v deklarácii triedy neznamená, že objekty tejto triedy sú nemenné. Môžeme zmeniť polia Kat voľne namietať:

Cat cat = new Cat (); cat.setWeight (1); assertEquals (1, kat.getWeight ()); 

Len to nemôžeme predĺžiť.

Ak dôsledne dodržiavame pravidlá dobrého dizajnu, mali by sme triedu starostlivo vytvoriť a zdokumentovať alebo ju deklarovať konečné z bezpečnostných dôvodov. Pri vytváraní by sme však mali postupovať opatrne konečné triedy.

Všimnite si, že sa robí hodina konečné znamená, že ho nemôže vylepšiť žiadny iný programátor. Predstavte si, že používame triedu a nemáme pre ňu zdrojový kód, a nastal problém s jednou metódou.

Ak je trieda konečné, nemôžeme ho rozšíriť, aby prepísal metódu a vyriešil problém. Inými slovami, prichádzame o rozšíriteľnosť, jednu z výhod objektovo orientovaného programovania.

3. Konečné Metódy

Metódy označené ako konečné nemožno prepísať. Keď navrhneme triedu a máme pocit, že metóda by nemala byť prepísaná, môžeme túto metódu vyrobiť konečné. Nájdeme ich tiež veľa konečné metódy v jadrových knižniciach Java.

Niekedy nemusíme úplne zakázať rozšírenie o triedu, iba zabránime prepísaniu niektorých metód. Dobrým príkladom toho je Závit trieda. Je legálne rozšíriť ho a vytvoriť tak vlastnú triedu vlákien. Ale jeho je nažive() metód je konečné.

Táto metóda kontroluje, či je vlákno živé. Nie je možné prekonať je nažive() metódu správne z mnohých dôvodov. Jedným z nich je, že táto metóda je pôvodná. Natívny kód je implementovaný v inom programovacom jazyku a často je špecifický pre operačný systém a hardvér, na ktorom beží.

Poďme vytvoriť pes triedy a vyrobiť jeho zvuk () metóda konečné:

public class Dog {public final void sound () {// ...}}

Teraz si rozšírme pes triedy a pokúsiť sa prepísať zvuk () metóda:

public class BlackDog rozširuje Dog {public void sound () {}}

Uvidíme chybu kompilátora:

- prepíše com.baeldung.finalkeyword.Dog.sound - Poslednú metódu nie je možné prepísať z metódy Dog sound () je konečná a nemožno ju prepísať.

Ak sú niektoré metódy našej triedy volané inými metódami, mali by sme zvážiť uskutočnenie týchto metód konečné. Inak môže ich potlačenie ovplyvniť prácu volajúcich a spôsobiť prekvapivé výsledky.

Ak náš konštruktor volá iné metódy, mali by sme tieto metódy všeobecne deklarovať konečné z vyššie uvedeného dôvodu.

Aký je rozdiel medzi výrobou všetkých metód triedy konečné a označenie samotnej triedy konečné? V prvom prípade môžeme triedu rozšíriť a pridať do nej nové metódy.

V druhom prípade to nemôžeme urobiť.

4. Konečné Premenné

Premenné označené ako konečné nie je možné prideliť. Raz konečné premenná je inicializovaná, nemožno ju meniť.

4.1. Konečné Primitívne premenné

Vyhlásime primitívu konečné premenná ja, potom mu priraďte 1.

Skúsme mu priradiť hodnotu 2:

public void whenFinalVariableAssign_thenOnlyOnce () {final int i = 1; // ... i = 2; }

Kompilátor hovorí:

Konečná lokálna premenná i už mohla byť priradená

4.2. Konečné Referenčné premenné

Ak máme a konečné referenčnú premennú, nemôžeme ju tiež znova priradiť. ale to neznamená, že objekt, na ktorý odkazuje, je nemenný. Vlastnosti tohto objektu môžeme ľubovoľne meniť.

Aby sme to demonštrovali, deklarujme konečné referenčná premenná kat a inicializovať:

konečná mačka mačka = nová mačka ();

Ak sa ho pokúsime znova priradiť, zobrazí sa chyba kompilátora:

Finálnu lokálnu premennú mačka nie je možné priradiť. Musí byť prázdne a nesmie obsahovať zložené priradenie

Ale môžeme zmeniť vlastnosti Kat inštancia:

cat.setWeight (5); assertEquals (5, kat.getWeight ());

4.3. Konečné Polia

Konečné polia môžu byť buď konštantné, alebo jednorazové. Aby sme ich rozlíšili, mali by sme si položiť otázku - zahrnuli by sme toto pole, keby sme mali objekt serializovať? Ak nie, potom to nie je súčasť objektu, ale konštanta.

Upozorňujeme, že podľa konvencií pomenovania by mali byť konštanty triedy veľké, pričom komponenty by mali byť oddelené znakmi podčiarknutia („_“):

statický konečný int MAX_WIDTH = 999;

Poznač si to akýkoľvek konečné pole musí byť inicializované pred dokončením konštruktora.

Pre statické finále to znamená, že ich môžeme inicializovať:

  • po vyhlásení, ako je uvedené vo vyššie uvedenom príklade
  • v statickom inicializačnom bloku

Napríklad konečné to znamená, že ich môžeme inicializovať:

  • po vyhlásení
  • v bloku inicializátora inštancie
  • v konštruktore

Inak nám kompilátor dá chybu.

4.4. Konečné Argumenty

The konečné kľúčové slovo je tiež legálne dať pred argumenty metódy. A konečné argument nemožno zmeniť v metóde:

public void methodWithFinalArguments (final int x) {x = 1; }

Vyššie uvedené priradenie spôsobí chybu kompilátora:

Konečnú lokálnu premennú x nemožno priradiť. Musí byť prázdne a nesmie obsahovať zložené priradenie

5. Záver

V tomto článku sme sa dozvedeli, čo konečné prostriedky pre kľúčové slová pre triedy, metódy a premenné. Aj keď nemusíme používať konečné kľúčové slovo často v našom internom kóde, môže to byť dobré dizajnové riešenie.

Kompletný kód tohto článku nájdete ako vždy v projekte GitHub.