Rozdiely medzi konečnou, konečnou a finalizáciou v Jave

1. Prehľad

V tomto výučbe sa zameriame na prehľad troch kľúčových slov Java: konečne, konečne a dokončiť.

Aj keď sa tieto kľúčové slová navzájom podobajú, má každé v Jave veľmi odlišný význam. Dozvieme sa účel každého z nich a ukážeme si niektoré príklady prostredníctvom trochy kódu.

2. konečné Kľúčové slovo

Najprv sa pozrime na konečné kľúčové slovo, kde ho použiť a prečo. Môžeme použiť konečné kľúčové slovo pre deklaráciu parametrov triedy, metódy, poľa, premennej a metódy.

Nemá to však rovnaký účinok na každú z nich:

  • Tvorba triedy konečné znamená, že nebude možné rozšíriť túto triedu
  • Pridávanie konečné znamená, že túto metódu nebude možné prepísať
  • Nakoniec uvedenie konečné pred poľom znamená premenná alebo parameter, že akonáhle je referencia priradená, nemôže byť zmenená (ak sa však jedná o mutabilný objekt, jeho vnútorný stav sa môže zmeniť napriek tomu, že je konečný)

Podrobný článok o konečné kľúčové slovo nájdete tu.

Pozrime sa, ako konečné kľúčové slovo funguje prostredníctvom niekoľkých príkladov.

2.1. konečné Polia, parametre a premenné

Vytvorme a Rodič trieda s dvoma int polia, a konečné jeden a bežný nefinálový:

public class Parent {int pole1 = 1; konečné int pole2 = 2; Rodič () {pole1 = 2; // OK pole2 = 3; // chyba kompilácie}}

Ako vidíme, kompilátor nám zakazuje priradiť novú hodnotu pole2.

Teraz pridajme metódu s regulárnym a konečným argumentom:

 void method1 (int arg1, final int arg2) {arg1 = 2; // OK arg2 = 3; // chyba kompilácie}

Podobne ako v poliach, aj tu nie je možné niečo priradiť arg2 pretože je vyhlásený za konečný.

Teraz môžeme pridať druhú metódu na ilustráciu toho, ako to funguje s lokálnymi premennými:

 void method2 () {final int localVar = 2; // OK localVar = 3; // chyba kompilácie}

Nič prekvapujúce sa nestane, kompilátor nám nedovolí priradiť novú hodnotu localVar po jeho prvom pridelení.

2.2. konečné Metóda

Teraz predpokladajme, že robíme metóda2 konečné a vytvoriť podtriedu Rodič, povedzme Dieťa, v ktorom sa pokúsime prekonať obe jeho metódy nadtriedy:

public class Child extends Parent {@Override void method1 (int arg1, int arg2) {// OK} @Override final void method2 () {// Chyba kompilácie}}

Ako vidíme, s prepísaním nie je problém metóda1 (), ale pri pokuse o prepísanie sa nám zobrazí chyba kompilácie metóda2 ().

2.3. konečné Trieda

A nakoniec urobme Dieťa finále triedy a pokúsiť sa vytvoriť jej podtriedu, GrandChild:

verejná posledná trieda Dieťa rozširuje rodiča {// ...}
verejná trieda GrandChild rozširuje podradenú {// chybu kompilácie}

Znova sa kompilátor sťažuje. The Dieťa trieda je konečná, a preto ju nemožno predĺžiť.

3. konečne Blokovať

The konečne blok je voliteľný blok na použitie s a Skús chytiť vyhlásenie. V tomto bloku zahrnujeme kód, ktorý sa má vykonať po Skús chytiť štruktúra, či je vyvolaná výnimka alebo nie.

Je dokonca možné ho použiť s skús blok bez akýchkoľvek chytiť blok za predpokladu, že obsahujeme a konečne blokovať. Kód sa potom vykoná po skús alebo po vyhodení výnimky.

Máme tu podrobný článok o spracovaní výnimiek v Jave.

Teraz si ukážeme konečne blok v krátkom príklade. Vytvoríme figurínu hlavný() metóda s a skúsiť / chytiť / konečne štruktúra:

public static void main (String args []) {try {System.out.println ("Execute try block"); hodiť novú Výnimku (); } catch (Výnimka e) {System.out.println ("Vykonať blok blokovania"); } konečne {System.out.println ("Vykonať konečne blok"); }}

Ak spustíme tento kód, vygeneruje sa toto:

Execute try block Execute catch block Execute konečne blokovať

Poďme teraz upraviť metódu odstránením bloku catch (a pridať hodí Výnimka k podpisu):

public static void main (String args []) vyvolá výnimku {try {System {out.println ("Execute try block"); hodiť novú Výnimku (); } konečne {System.out.println ("Vykonať konečne blok"); }}

Výstup je teraz:

Execute try block Execute konečne blokovať

Ak teraz odstránime hodiť novú výnimku () inštrukcie môžeme pozorovať, že výstup zostáva rovnaký. Náš konečne spustenie bloku nastane zakaždým.

4. dokončiť Metóda

A nakoniec dokončiť metóda je chránená metóda definovaná v triede Object. Volá sa to smetiar na objektoch, na ktoré sa už neodkazuje a boli vybrané na zber odpadu.

Ako každá iná konečná metóda, aj túto metódu môžeme prepísať, aby sme definovali správanie, ktoré musí mať objekt, keď ho zhromažďuje smetiar.

Opäť podrobný článok o dokončiť metódu nájdete tu.

Pozrime sa na príklad, ako to funguje. Použijeme System.gc () navrhnúť JVM Spustiť odvoz odpadu:

 @Override protected void finalize () hodí Throwable {System.out.println ("Vykonať finalizačnú metódu"); super.finalizovať (); }
 public static void main (String [] args) vyvolá Výnimku {FinalizeObject objekt = nový FinalizeObject (); objekt = null; System.gc (); Závit. Spánok (1 000); }

V tomto príklade prepíšeme dokončiť () metóda v našom objekte a vytvorte a hlavný() metóda, ktorá vytvorí inštanciu nášho objektu a okamžite zruší referenciu nastavením vytvorenej premennej na nulový.

Potom voláme System.gc () spustiť smetiar (aspoň očakávame, že sa spustí) a chvíľu počkajte (len aby sme zaistili, že JVM nevypína sa skôr smetiar má možnosť zavolať dokončiť () metóda).

Výstupom tohto vykonania kódu by malo byť:

Vykonajte finalizačnú metódu

Upozorňujeme, že prepísanie sa považuje za zlý postup dokončiť () metóda, pretože jej vykonávanie závisí od odvoz odpadu ktorý je v rukách JVM. Navyše táto metóda bola zastarané od Javy 9.

5. Záver

V tomto článku sme stručne diskutovali o rozdieloch medzi tromi kľúčovými slovami podobnými jazyku Java: konečne, konečne a dokončiť.

Celý kód článku nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found