JAVA PAGRINDAI DETALIAU
Java final raktažodis
final raktažodis (angl. final keyword) apriboja vėlesnius pakeitimus. Kintamajam jis draudžia antrą priskyrimą, metodui – perrašymą poklasyje, o klasei – paveldėjimą.
Trys pagrindinės naudojimo vietos
| Kur rašomas? | Ką apriboja? | Ko nedaro? |
|---|---|---|
| Prie kintamojo | Reikšmę arba nuorodą galima priskirti tik vieną kartą | Ne visada padaro nurodomą objektą nekeičiamą |
| Prie metodo | Poklasis negali metodo perrašyti | Nedraudžia metodo paveldėti ir iškviesti |
| Prie klasės | Kita klasė negali jos paveldėti su extends | Nedraudžia kurti klasės objektų |
1. final kintamasis priskiriamas vieną kartą
Veikiantis pavyzdys
final int MINIMALUS_AMZIUS = 18;
System.out.println(MINIMALUS_AMZIUS);18
- Kintamajam
MINIMALUS_AMZIUSpirmą kartą priskiriame18. - Šią reikšmę galima skaityti ir naudoti skaičiavimuose.
finalnereiškia, kad reikšmė privalo būti žinoma kompiliavimo metu – svarbu, kad ji būtų priskirta tik kartą.
Nesikompiliuojantis pavyzdys
final int MINIMALUS_AMZIUS = 18;
MINIMALUS_AMZIUS = 21; // Klaida: antras priskyrimas neleidžiamasKodas nesukompiliuojamas. Klaidinga eilutė palikta aktyvi, o jos pabaigoje esantis komentaras paaiškina priežastį: final kintamajam jau buvo priskirta reikšmė.
Reikšmę galima suteikti konstruktoriuje
Klasės final lauką galima deklaruoti be reikšmės ir priskirti jį kiekviename konstruktoriuje. Tai vadinama tuščiuoju final lauku (angl. blank final field).
class Uzsakymas {
final int numeris;
String pirkejas;
Uzsakymas(int numeris, String pirkejas) {
this.numeris = numeris;
this.pirkejas = pirkejas;
}
}
Uzsakymas uzsakymas = new Uzsakymas(1042, "Ieva");
System.out.println(uzsakymas.numeris);
System.out.println(uzsakymas.pirkejas);1042
Ieva
Kiekvienas Uzsakymas objektas gali turėti kitą numerį, tačiau jau sukurto objekto numerio perrašyti nebegalima.
class Uzsakymas {
final int numeris;
Uzsakymas() {
// Klaida: numeris liko be reikšmės
}
}Kodas nesukompiliuojamas. Kiekvienas konstruktoriaus kelias privalo suteikti final laukui reikšmę tiksliai vieną kartą.
final nuoroda nereiškia nekintamo objekto
Veikiantis pavyzdys: keičiamas objekto turinys
final StringBuilder tekstas = new StringBuilder("Pirkinių sąrašas");
tekstas.append(": duona, pienas");
System.out.println(tekstas);Pirkinių sąrašas: duona, pienas
finalužrakina nuorodątekstasprie vienoStringBuilderobjekto.- Pats
StringBuilderyra keičiamas, todėl jo turinį galima papildyti suappend().
Nesikompiliuojantis pavyzdys: nuoroda nukreipiama kitur
final StringBuilder tekstas = new StringBuilder("Pirkinių sąrašas");
tekstas = new StringBuilder("Kitas sąrašas"); // Klaida: antras priskyrimasKodas nesukompiliuojamas. Keičiama ne seno objekto būsena, o pats kintamasis tekstas bandomas nukreipti į kitą objektą.
final nuoroda ir nekintamas (angl. immutable) objektas nėra tas pats. Nekintamumui reikia ir tinkamo pačios klasės dizaino.
static final – bendra klasės konstanta
class Laikas {
static final int MINUCIU_PER_VALANDA = 60;
static final int SEKUNDZIU_PER_MINUTE;
static {
SEKUNDZIU_PER_MINUTE = 60;
}
}
int sekundziu = 2
* Laikas.MINUCIU_PER_VALANDA
* Laikas.SEKUNDZIU_PER_MINUTE;
System.out.println(sekundziu);7200
staticreiškia, kad visa klasė turi vieną bendrą reikšmę.finalneleidžia jos priskirti antrą kartą.- Reikšmę galima suteikti iš karto arba statiniame inicializavimo bloke.
- Konstantų vardai įprastai rašomi
UPPER_SNAKE_CASEstiliumi.
final metodų parametrai ir vietiniai kintamieji
Veikiantis pavyzdys
class Pasisveikinimas {
static String sukurti(final String vardas) {
return "Labas, " + vardas + "!";
}
}
System.out.println(Pasisveikinimas.sukurti("Rūta"));Labas, Rūta!
final parametrui metodo viduje negalima priskirti kitos reikšmės. Tai gali parodyti ketinimą parametro nekeisti, tačiau objekto parametro vidinė būsena ir toliau gali būti keičiama, jei jo klasė tai leidžia.
Nesikompiliuojantis pavyzdys
class Pasisveikinimas {
static String sukurti(final String vardas) {
vardas = "Kitas vardas"; // Klaida: final parametro keisti negalima
return "Labas, " + vardas + "!";
}
}Kodas nesukompiliuojamas, nes metodo viduje parametrui vardas bandoma priskirti kitą tekstą.
2. final metodo negalima perrašyti
class Mokestis {
final double galutineKaina(double kaina) {
return kaina * 1.21;
}
}
class SpecialusMokestis extends Mokestis {
double galutineKaina(double kaina) { // Klaida: final metodo perrašyti negalima
return kaina;
}
}Kodas nesukompiliuojamas, nes galutineKaina(double) pažymėtas final.
final metodas naudojamas tada, kai poklasiai neturi teisės pakeisti svarbios taisyklės ar algoritmo. Tačiau jie vis tiek paveldi metodą ir gali jį iškviesti:
class Mokestis {
final double galutineKaina(double kaina) {
return kaina * 1.21;
}
}
class PvmMokestis extends Mokestis {
void rodyti(double kaina) {
System.out.println(galutineKaina(kaina));
}
}
PvmMokestis mokestis = new PvmMokestis();
mokestis.rodyti(100);121.0
3. final klasės negalima paveldėti
final class AsmensKodas {
private final String reiksme;
AsmensKodas(String reiksme) {
this.reiksme = reiksme;
}
String gauti() {
return reiksme;
}
}
class SpecialusKodas extends AsmensKodas { // Klaida: final klasės paveldėti negalima
SpecialusKodas(String reiksme) {
super(reiksme);
}
}Kodas nesukompiliuojamas, nes SpecialusKodas bando paveldėti final klasę AsmensKodas.
final klasė užbaigia paveldėjimo grandinę. Tai naudinga, kai klasės elgesio negalima saugiai pakeisti per poklasį arba kai jos nekintamumo taisyklės priklauso nuo visiškai kontroliuojamos struktūros.
String yra final klasė. Kita klasė negali jos paveldėti ir pakeisti teksto elgsenos.
Ko final negarantuoja?
finalnuoroda negarantuoja, kad objektas yra nekintamas.finalklasė savaime negarantuoja nekintamumo – jos laukai vis tiek gali būti keičiami.finalnepadaro kodo automatiškai saugaus kelioms gijoms.finalnėra prieigos modifikatorius ir nesprendžia, kas gali narį matyti.finalirfinallyyra skirtingi Java raktažodžiai, atliekantys skirtingas užduotis.
Kada verta naudoti?
| Situacija | Sprendimas |
|---|---|
| Reikšmė ar nuoroda po priskyrimo neturi keistis | final kintamasis |
| Bendra visos klasės konstanta | static final laukas |
| Poklasiai gali paveldėti metodą, bet negali keisti jo taisyklės | final metodas |
| Klasė neturi turėti poklasių | final klasė |
| Objektas turi būti visiškai nekintamas | Vien final nepakanka – reikia nekintamos klasės dizaino |
Ką verta prisiminti?
finalkintamajam leidžia tik vieną priskyrimą.- Tuščias
finallaukas turi būti inicializuotas kiekviename konstruktoriuje. finalnuoroda negali rodyti į kitą objektą, bet pats objektas gali likti keičiamas.finalmetodo negalima perrašyti, tačiau galima paveldėti ir iškviesti.finalklasės negalima paveldėti.static finaldažniausiai naudojamas bendroms klasės konstantoms.

