Razlike između Final, Final i Finalize u Javi

1. Pregled

U ovom uputstvu dat ćemo pregled tri ključne riječi Java: konačno, konačno i dovršiti.

Iako ove ključne riječi sliče jedna drugoj, svaka na Java ima vrlo različito značenje. Naučit ćemo svrhu svakog od njih i vidjeti ćemo nekoliko primjera kroz malo koda.

2. konačni Ključna riječ

Pogledajmo prvo konačni ključna riječ, gdje je koristiti i zašto. Možemo primijeniti konačni ključna riječ za deklaracije klase, metode, polja, varijable i parametra metode.

Ipak nema isti učinak na svakog od njih:

  • Izrada predavanja konačni znači da neće biti moguće proširiti tu klasu
  • Dodavanje konačni na metodu znači da neće biti moguće poništiti tu metodu
  • Napokon, stavljanje konačni ispred polja, varijabla ili parametar znači da nakon što je referenca dodijeljena, ona se ne može mijenjati (međutim, ako je referenca na promjenjivi objekt, njezino unutarnje stanje može se promijeniti unatoč konačnosti)

Detaljan članak o konačni ključnu riječ možete pronaći ovdje.

Da vidimo kako konačni ključna riječ djeluje kroz neke primjere.

2.1. konačni Polja, parametri i varijable

Stvorimo a Roditelj razred s dvoje int polja, a konačni jedan i redoviti ne-konačni:

javna klasa Roditelj {int field1 = 1; završno int polje2 = 2; Roditelj () {polje1 = 2; // U redu polje2 = 3; // Pogreška kompilacije}}

Kao što vidimo, kompajler nam zabranjuje dodijeliti novu vrijednost polje2.

Dodajmo sada metodu s redovnim i završnim argumentom:

 void method1 (int arg1, final int arg2) {arg1 = 2; // U redu arg2 = 3; // pogreška kompilacije}

Slično poljima nije moguće nešto dodijeliti arg2 kao što je proglašeno konačnim.

Sada možemo dodati drugu metodu koja će ilustrirati kako ovo funkcionira s lokalnim varijablama:

 void method2 () {final int localVar = 2; // U redu localVar = 3; // pogreška kompilacije}

Ništa se iznenađujuće ne događa, kompajler nam ne dopušta dodijeliti novu vrijednost localVar nakon prvog dodjeljivanja.

2.2. konačni Metoda

Sad pretpostavimo da jesmo metoda2 konačni i stvoriti podrazred od Roditelj, recimo Dijete, u kojem pokušavamo poništiti obje njegove metode superrazreda:

javna klasa Dijete proširuje roditelj {@Override void method1 (int arg1, int arg2) {// OK} @Override final void method2 () {// Pogreška kompilacije}}

Kao što vidimo, nema problema s poništavanjem metoda1 (), ali dobivamo pogrešku u kompilaciji kada pokušavamo poništiti metoda2 ().

2.3. konačni Razred

I na kraju, napravimo Dijete razred završni i pokušajte stvoriti njegov podrazred, Unuče:

javni završni razred Dijete produžuje roditelj {// ...}
javna klasa GrandChild proširuje Child {// Pogreška kompilacije}

Još jednom se sastavljač žali. The Dijete razred je konačan i stoga ga je nemoguće produžiti.

3. konačno Blok

The konačno blok je neobavezni blok za upotrebu s a pokušaj uhvatiti izjava. U ovaj blok uključujemo kod koji treba izvršiti nakon pokušaj uhvatiti struktura, bez obzira je li izuzetak izbačen ili ne.

Moguće ga je koristiti i sa probati blok bez ikakvog ulov blok pod uvjetom da uključujemo a konačno blok. Kôd će se zatim izvršiti nakon probati ili nakon što se izuzetak izbaci.

Ovdje imamo detaljni članak o rukovanju iznimkama na Javi.

Sada pokažimo a konačno blok u kratkom primjeru. Stvorit ćemo lutku glavni() metoda s a probaj / uhvati / napokon struktura:

javna statička void glavna (String args []) {try {System.out.println ("Izvrši blok pokušaja"); baciti novi Exception (); } catch (Iznimka e) {System.out.println ("Izvrši blok catch"); } napokon {System.out.println ("Izvršiti konačno blokiranje"); }}

Ako pokrenemo ovaj kôd, on će dati sljedeće:

Izvrši pokušaj bloka Izvrši blok catch Izvrši konačno block

Izmijenimo sada metodu uklanjanjem bloka catch (i dodajte baca Izuzetak do potpisa):

javna statička void glavna (String args []) baca iznimku {try {System.out.println ("Izvrši blok pokušaja"); baciti novi Exception (); } napokon {System.out.println ("Izvršiti konačno blokiranje"); }}

Izlaz je sada:

Izvrši pokušaj bloka Izvrši konačno blok

Ako sada uklonimo baci novi izuzetak () Upute, možemo primijetiti da izlaz ostaje isti. Naše konačno izvršenje bloka događa se svaki put.

4. dovršiti Metoda

I na kraju, dovršiti metoda je zaštićena metoda, definirana u klasi Object. Zove ga sakupljač smeća na objektima na koje više nema referenci i koji su odabrani za odvoz smeća.

Kao i bilo koja druga ne-konačna metoda, možemo nadjačati ovu metodu kako bismo definirali ponašanje koje objekt mora imati kada ga prikuplja sakupljač smeća.

Opet, detaljan članak koji pokriva dovršiti metodu možete pronaći ovdje.

Pogledajmo primjer kako to funkcionira. Koristit ćemo System.gc () predložiti JVM okinuti kolekcija smeća:

 @Override protected void finalize () baca mogućnost bacanja {System.out.println ("Izvrši metodu finalizacije"); super.finalize (); }
 javna statička void glavna (String [] args) baca iznimku {FinalizeObject objekt = novi FinalizeObject (); objekt = null; System.gc (); Navoj.spavanje (1000); }

U ovom primjeru poništavamo finalizirati () metodu u našem objektu i stvorimo a glavni() metoda koja instancira naš objekt i odmah ispušta referencu postavljanjem kreirane varijable na null.

Nakon toga zovemo System.gc () pokrenuti sakupljač smeća (barem očekujemo da se pokrene) i pričekajte sekundu (samo da bismo osigurali da JVM ne zatvori prije sakupljač smeća ima priliku nazvati finalizirati () metoda).

Rezultat ovog izvršavanja koda trebao bi biti:

Izvršiti metodu finaliziranja

Imajte na umu da se smatra lošom praksom nadjačavanja finalizirati () metoda jer njezino izvršenje ovisi o kolekcija smeća koja je u ruci JVM. Osim toga, ova metoda je bila zastarjelo od Jave 9.

5. Zaključak

U ovom smo članku ukratko razgovarali o razlikama između tri slične ključne riječi Java: konačno, konačno i dovršiti.

Cjelokupni kod članka možete pronaći na GitHubu.