JAVA PAGRINDAI DETALIAU
Java static raktažodis
static raktažodis (angl. static keyword) nurodo, kad laukas, metodas, blokas arba įdėtinė klasė priklauso pačiai klasei, o ne atskiram jos objektui. Tokį narį klasė turi bendrą, todėl jam pasiekti dažnai nereikia kurti objekto.
Klasė ar konkretus objektas?
| Savybė | static narys | Egzemplioriaus narys |
|---|---|---|
| Kam priklauso? | Klasei | Konkrečiam objektui |
| Kiek reikšmių? | Viena bendra klasės reikšmė | Kiekvienas objektas turi savo reikšmę |
| Kaip pasiekiamas? | Rekomenduojama per klasės pavadinimą | Per objekto nuorodą |
| Kam tinka? | Konstantoms, bendriems skaitikliams, pagalbiniams metodams | Konkretaus objekto būsenai ir elgesiui |
1. Statinis laukas – viena bendra reikšmė
class Lankytojas {
String vardas;
static int sukurtuObjektu = 0;
Lankytojas(String vardas) {
this.vardas = vardas;
sukurtuObjektu++;
}
}
Lankytojas pirmas = new Lankytojas("Ieva");
Lankytojas antras = new Lankytojas("Mantas");
System.out.println(pirmas.vardas);
System.out.println(antras.vardas);
System.out.println(Lankytojas.sukurtuObjektu);Ieva
Mantas
2
- Kiekvienas
Lankytojasobjektas turi savo laukąvardas. sukurtuObjektupažymėtasstatic, todėl visa klasė turi vieną bendrą skaitiklį.- Kiekvienas konstruktoriaus iškvietimas padidina tą pačią bendrą reikšmę.
- Statinį lauką skaitome per klasę:
Lankytojas.sukurtuObjektu.
2. Statinis metodas – veiksmui nereikia objekto
class Temperaturos {
static double iFarenheita(double celsijai) {
return celsijai * 9 / 5 + 32;
}
}
double rezultatas = Temperaturos.iFarenheita(20);
System.out.println(rezultatas);68.0
Metodas skaičiavimui naudoja tik perduotą parametrą ir jam nereikia jokios konkretaus Temperaturos objekto būsenos. Todėl jį prasminga žymėti static ir kviesti per klasę.
Kodėl statinis metodas tiesiogiai nemato objekto laukų?
class Pirkejas {
String vardas = "Rūta";
static void rodytiVarda() {
// Klaida: vardas priklauso konkrečiam objektui
System.out.println(vardas);
}
}Kodas nesukompiliuojamas. Statinis metodas gali būti iškviestas nesukūrus nė vieno Pirkejas objekto, todėl Java nežino, kurio pirkėjo vardą reikėtų rodyti.
Jei statiniam metodui reikia objekto duomenų, objektą perduok aiškiai:
class Pirkejas {
String vardas;
Pirkejas(String vardas) {
this.vardas = vardas;
}
static void rodytiVarda(Pirkejas pirkejas) {
System.out.println(pirkejas.vardas);
}
}
Pirkejas pirkejas = new Pirkejas("Rūta");
Pirkejas.rodytiVarda(pirkejas);Rūta
Dėl tos pačios priežasties statiniame kontekste negalima naudoti this ar super: nėra vieno dabartinio objekto.
Kviesti per klasę ar per objektą?
class Skaiciuotuvas {
static int dvigubinti(int skaicius) {
return skaicius * 2;
}
}
Skaiciuotuvas objektas = new Skaiciuotuvas();
System.out.println(Skaiciuotuvas.dvigubinti(5)); // Rekomenduojama
System.out.println(objektas.dvigubinti(5)); // Veikia, bet klaidina10
10
Abi formos kompiliuojamos, tačiau objektas.dvigubinti(5) sudaro klaidingą įspūdį, kad naudojama konkretaus objekto būsena. Rašyk Skaiciuotuvas.dvigubinti(5) – taip iš karto matyti, kad metodas priklauso klasei.
3. Statinis inicializavimo blokas
class Nustatymai {
static String valiuta;
static int pristatymoDienos;
static {
System.out.println("Įkeliami nustatymai");
valiuta = "EUR";
pristatymoDienos = 3;
}
}
System.out.println(Nustatymai.valiuta);
System.out.println(Nustatymai.pristatymoDienos);Įkeliami nustatymai
EUR
3
- Statinis blokas vykdomas vieną kartą inicijuojant klasę.
- Jis įvykdomas prieš pirmą aktyvų statinių laukų naudojimą.
- Blokas tinka sudėtingesniam statinių laukų paruošimui, kurio nepatogu užrašyti viena išraiška.
Paslėptas failų, tinklo ar duomenų bazės darbas statiniame bloke apsunkina testavimą ir klaidų valdymą. Paprastoms konstantoms dažniausiai pakanka tiesioginio priskyrimo.
static final konstantos
class MatavimoVienetai {
static final int MINUCIU_PER_VALANDA = 60;
static final int SEKUNDZIU_PER_MINUTE = 60;
}
int sekundziu = 2
* MatavimoVienetai.MINUCIU_PER_VALANDA
* MatavimoVienetai.SEKUNDZIU_PER_MINUTE;
System.out.println(sekundziu);7200
static reiškia, kad reikšmė priklauso klasei, o final – kad nuorodos ar primityviosios reikšmės negalima priskirti iš naujo. Konstantų vardai įprastai rašomi didžiosiomis raidėmis su pabraukimais.
4. Statinė įdėtinė klasė
class Adresas {
static class Tikrintuvas {
boolean tinkamasPastoKodas(String kodas) {
return kodas != null && kodas.length() == 5;
}
}
}
Adresas.Tikrintuvas tikrintuvas = new Adresas.Tikrintuvas();
System.out.println(tikrintuvas.tinkamasPastoKodas("01100"));true
Adresas.Tikrintuvas logiškai priklauso Adresas temai, tačiau jo objektui nereikia išorinio Adresas objekto. static galima taikyti įdėtinei klasei, bet ne paprastai aukščiausio lygio klasei.
Kodėl main() yra statinis?
Java virtualioji mašina turi pradėti programą dar neturėdama tavo klasės objekto. Todėl ji gali tiesiogiai iškviesti klasės metodą:
public static void main(String[] args)
Jei main() nebūtų static, pirmiausia reikėtų objekto, tačiau dar nebūtų jokio metodo, kuris tą objektą programos pradžioje sukurtų.
Statiniai metodai nėra perrašomi
Jei poklasis aprašo tokio pat parašo statinį metodą, jis tėvinį metodą paslepia, o ne perrašo. Pasirinkimas atliekamas pagal nuorodos ar klasės vardą, o ne pagal tikrąjį objektą.
Kada naudoti, o kada vengti?
| Geras pasirinkimas | Reikia atsargumo |
|---|---|
| Nekintamos bendros konstantos | Keičiama globali būsena |
| Gryni pagalbiniai skaičiavimai | Duomenys, kurie iš tikrųjų priklauso objektui |
| Aiškūs objektų skaitikliai | Bendra būsena kelioms gijoms be sinchronizavimo |
| Objektų kūrimo metodai | Priklausomybės, kurias reikės pakeisti testuose |
Keičiamas statinis laukas veikia kaip bendra programos būsena. Jį gali keisti daugelis objektų, todėl didesnėje programoje tampa sunkiau suprasti, kas ir kada pakeitė reikšmę. Kelių gijų aplinkoje dar reikia pasirūpinti saugia prieiga.
Ką verta prisiminti?
staticnarys priklauso klasei, o ne konkrečiam objektui.- Statinius laukus ir metodus kviesk per klasės pavadinimą.
- Statinis laukas yra bendras visiems tos klasės objektams.
- Statinis metodas tiesiogiai nemato egzemplioriaus laukų ir negali naudoti
thisarsuper. - Statinis blokas vykdomas vieną kartą inicijuojant klasę.
static finaldažnai naudojamas bendroms konstantoms.- Statinės gali būti tik įdėtinės, o ne aukščiausio lygio klasės.
- Keičiamą bendrą statinę būseną naudok atsargiai.

