Jedan članak da potpuno razumete Java final ključnu reč
"Brate, šta danas učimo?"
"Danas učimo jednu važnu ključnu reč — final." odgovorio sam joj sa prosto, neukrašenim osmehom. "Usput, Sanmej, da li planiraš postdiplomske studije?"
"Nisam razmišljala o tome, tek sam na prvoj godini, neka bude za kasnije, ti odluči."
"Dobro." Slegnuo sam ramenima, izgledajući potpuno nedužno. Zaista, svaka odluka prelazi na mene kao starijeg brata; ako odaberem pogrešno, snosim krivicu.
01. final promenljiva
"Dobro, hajde da prvo pogledamo final modifikovane promenljive!"
"Promenljiva modifikovana sa final ne može biti ponovo dodeljena. Drugim rečima, jednom kada se final promenljiva inicijalizuje, ne može se više menjati."
"Pogledaj ovaj red koda."
final int age = 18;"Kada pokušaš da promeniš vrednost age na 30, kompajler se naljuti."

"Pogledaj sada ovaj kod."
public class Pig {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}"Ovo je sasvim obična Java klasa koja ima polje name."
"Zatim kreiramo test klasu i deklarišemo final modifikovan Pig objekat."
final Pig pig = new Pig();"Ako pokušamo da ponovo dodelimo pig, kompajler će se opet naljutiti."

"Ali i dalje možemo da menjamo name pig objekta."
final Pig pig = new Pig();
pig.setName("Te li du xing");
System.out.println(pig.getName()); // Te li du xing"Pored toga, final modifikovana članska promenljiva mora imati podrazumevanu vrednost, inače će kompajler prijaviti da nije inicijalizovana."

"final i static zajedno modifikovana članska promenljiva zove se konstanta, a ime konstante mora biti potpuno velikim slovima."
public class Pig {
private final int age = 1;
public static final double PRICE = 36.5;
}"Ponekad takođe koristimo final ključnu reč za modifikaciju parametara, što znači da parametar ne može biti ponovo izmenjen u telu metode."
"Pogledaj sledeći kod."
public class ArgFinalTest {
public void arg(final int age) {
}
public void arg1(final String name) {
}
}"Ako pokušaš da ga izmeniš, kompajler će prikazati sledeću grešku."

02. final metod
"Metod modifikovan sa final ne može biti prepraćivan (overridden). Ako pri dizajniranju klase smatramo da neki metodi ne bi trebalo da budu prepraćivani, trebalo bi ih dizajnirati kao final."
"Thread klasa je jedan primer — sama klasa nije final, što znači da možemo da je proširimo, ali njen isAlive() metod je final."
public class Thread implements Runnable {
public final native boolean isAlive();
}"Važno je napomenuti da je ovaj metod lokalni (native) i služi da potvrdi da li je nit u aktivnom stanju. Pošto su lokalni metodi određeni operativnim sistemom, prepraćivanje ovog metoda nije lako izvesti."
"Pogledaj ovaj kod."
public class Actor {
public final void show() {
}
}"Kada pokušamo da prepišemo taj metod, dobićemo grešku pri kompajliranju."

"Sanmej, da ti postavim pitanje." Hteo sam da iskoristim priliku dok Sanmej odgovara na pitanje da popijem malo vode.
"Izvoli, brate."
"Jedna klasa je final, i jedna klasa nije final, ali su svi njeni metodi final — razmisli, koja je razlika između njih?"
"Jedna stvar koja mi pada na pamet je da prva ne može biti nasleđena, što znači da metodi ne mogu biti prepraćivani; druga može biti nasleđena, a zatim joj se mogu dodati neki ne-final metodi." Sanmej je odgovorila pre nego što sam stigao da progutam vodu, što me zaista iznenadilo.
"Hmm, nema greške, veliki napredak!"
"Pa naravno, ko je tvoja sestra."
03. final klasa
"Ako je klasa modifikovana sa final ključnom reči, onda ne može biti nasleđena..."
"Trenutak, brate, znam — String klasa je final klasa." Pre nego što sam završio, Sanmej je prekinula.
"Bez greške."
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {}"Da li znaš, Sanmej, zašto je String klasa dizajnirana kao final?"
"Zaista ne znam." Izraz njenog lica odavao je tu bespomoćnost.
"Razloga je otprilike tri."
- Da bi se implementirao bazen string konstanti
- Zbog bezbednosti niti
- Zbog nepromenljivosti HashCode-a
"Ako želiš detaljnije razloge, možeš kasnije pogledati članak koji sam ranije napisao."
Zašto su Java stringovi nepromenljivi?
"Svaki pokušaj nasleđivanja iz final klase izazvaće grešku pri kompajliranju. Pogledaj ovaj kod."
public final class Writer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}"Ako pokušaš da je naslediš, kompajler će prikazati sledeću grešku: Writer klasa je final i ne može se naslediti."

"Međutim, to da je klasa final ne znači da su objekti te klase nepromenljivi."
"Pogledaj ovaj kod."
Writer writer = new Writer();
writer.setName("Chenmo Wang Er");
System.out.println(writer.getName()); // Chenmo Wang Er"Podrazumevana vrednost polja name klasa Writer je null, ali se može promeniti u Chenmo Wang Er pomoću setter metoda. Drugim rečima, ako je klasa samo final, to nije dovoljan uslov za nepromenljivost."
"O nepromenljivim klasama ćemo detaljnije govoriti kasnije."
"Dizajniranje klase kao final ima svoje bezbednosne razloge, ali se ne bi trebalo raditi namerno, jer dizajniranje klase kao final znači da se ne može naslediti; ako neki metodi te klase imaju problema, ne možemo ih popraviti prepraćivanjem."
"Sanmej, final ključnu reč učimo do ovde, a ti kasnije prouči još zašto su Java stringovi nepromenljivi i šta su nepromenljive klase." Protrljao sam pospane oči i umorno rekao Sanmej. "Kada savladaš ove dve teme, biće ti jasnija slika o final."
"Dobro, Erge, idem odmah da učim. Ti se odmori."
Ustao sam i izašao na balkon, gledajući promet napolju, i ubrzo zapao u sanjarenje.
"Voleo bih da ponovo odem na koncert Džou Đieluna, ne znam da li ću imati priliku 2021."
Tako sam mislio u sebi, a nebo je postepeno potamnelo.
