count
mező statikus az osztályban Counter
, az azt jelenti, hogy a következő kifejezéssel hivatkozhat a változóra: Counter.count
. 
private
a mezők csak azon az osztályon belül érhetők el, amelyben deklarálva vannak. A protected
mezők a csomagon belüli összes osztály számára, valamint a csomagon kívüli összes alosztálya számára elérhetők. Tegyük fel, hogy az Counter
osztálynak van egy statikus increment()
metódusa, amelynek feladata a szám növelésecount
terület. Ennek a módszernek a meghívásához használhatja a Counter.increment()
. Nem szükséges létrehozni az Counter
osztály példányát egy statikus mező vagy metódus eléréséhez. Ez az alapvető különbség a statikus (osztály) változók és módszerek, valamint a NEM statikus (példány) változók és módszerek között. Fontos megjegyzés. Ne felejtsük el, hogy az osztály statikus tagjai közvetlenül az osztályhoz tartoznak, nem pedig az osztály bármely példányához. Vagyis a statikus count
változó értéke minden objektumnál azonos lesz Counter
. Ebben a cikkben megvizsgáljuk a statikus módosító Java-ban való használatának alapvető szempontjait, valamint néhány olyan szolgáltatást, amelyek segítenek megérteni a kulcsfontosságú programozási fogalmakat.
Amit minden programozónak tudnia kell a Java statikus módosítójáról.
Ebben a részben a statikus módszerek, mezők és osztályok használatának fő szempontjait tekintjük át. Kezdjük a változókkal.-
Egy statikus kontextusban, például statikus metódusban vagy blokkban NEM férhet hozzá egy osztály nem statikus tagjaihoz. Az alábbi kód összeállítása hibát eredményez:
public class Counter { private int count; public static void main(String args []) { System.out.println(count); // Compile time error } }
Ez az egyik leggyakoribb hiba, amelyet a Java programozók, különösen a kezdők követnek el. Mivel a
main
metódus statikus, acount
változó pedig nem, a metódusonprintln
belüli metódus használatamain
"fordítási idő hibát" eredményez. -
A helyi változókkal ellentétben a statikus mezők és metódusok NINCS
thread safe
a Java-ban. A gyakorlatban ez a biztonsági problémák egyik leggyakoribb oka a többszálú programozásban. Figyelembe véve, hogy egy osztály minden példánya egy statikus változó ugyanarra a másolatára hivatkozik, az ilyen változót az osztálynak védenie vagy „zárolnia” kell. Ezért statikus változók használatakor ügyeljen arra, hogy azok megfelelőek legyenek,synchronized
hogy elkerülje az olyan problémákat, mint plrace conditions
. -
A statikus módszerek gyakorlati előnye, hogy nem kell minden alkalommal új objektumot létrehozni, amikor meg akarjuk hívni őket. A statikus metódus az azt deklaráló osztály nevével hívható meg. Ezért ezek a módszerek tökéletesek
factory
a módszerekhez ésutility
módszerekhez. Azjava.lang.Math
osztály csodálatos példa: szinte minden metódusa statikus. A Java segédprogram osztályaifinal
ugyanezen okból vannak megjelölve. -
Egy másik fontos szempont, hogy nem bírálhatod felül a (
@Override
) statikus módszereket. Ha egy ilyen metódust deklarálunk egysubclass
, azaz azonos nevű és aláírású metódusban, akkorsuperclass
felülírás helyett csak "elrejti" a metódusát. Ezt a jelenségetmethod hiding
. Ez azt jelenti, hogy ha egy statikus metódus deklarálva van mind a szülő-, mind a gyermekosztályban, akkor a meghívott metódus mindig a fordításkor megnevezett változótípuson fog alapulni. A metódusok felülbírálásával ellentétben az ilyen metódusok nem kerülnek végrehajtásra a program futása közben. Nézzünk egy példát:class Vehicle { public static void kmToMiles(int km) { System.out.println("Inside the parent class / static method"); } } class Car extends Vehicle { public static void kmToMiles(int km) { System.out.println("Inside the child class / static method"); } } public class Demo { public static void main(String args []) { Vehicle v = new Car(); v.kmToMiles(10); } }
Konzol kimenet:
A szülő osztályon belül / statikus metóduson
A kód egyértelműen mutatja, hogy annak ellenére, hogy az objektum egy
Car
, az osztály statikus metódusaVehicle
hívódik meg, mivel a metódus fordítási időben lett meghívva. És vegye figyelembe, hogy nem volt fordítási hiba! -
Sőt, a legfelső szintű osztályokon kívül az osztályokat statikusnak is deklarálhatja. Az ilyen osztályokat
nested static classes
. Hasznosak a jobb kohézió biztosítására. A beágyazott statikus osztály szembetűnő példája aHashMap.Entry
, amely egy belső adatstruktúraHashMap
. Érdemes megjegyezni, hogy a belső osztályokhoz hasonlóan a statikus beágyazott osztályokat is külön .class fájlban deklarálják. Így ha öt beágyazott osztályt deklarál a főosztályodban, akkor 6 fájlod lesz .class kiterjesztéssel. Egy másik példa a saját deklarációnkComparator
, például egy életkor-összehasonlító (AgeComparator
) azEmployee
osztályban. -
A statikus módosító egy statikus blokkban is megadható, ismertebb nevén "statikus inicializálási blokkban", amely az osztály betöltésekor kerül végrehajtásra. Ha nem deklarál ilyen blokkot, a Java az összes statikus mezőt egyetlen listába gyűjti, és inicializálja őket az osztály betöltésekor. Egy statikus blokk NEM dobhat ellenőrzött kivételeket, de képes a nem ellenőrzött kivételeket. Ebben az esetben egy
ExceptionInInitializerError
lesz. A gyakorlatban a statikus mezők inicializálása során fellépő kivételeket a Java ebbe a hibába csomagolja. Ez a leggyakoribb oka aNoClassDefFoundError
, mert az osztály nem lesz a memóriában, amikor hivatkozik rá. -
Hasznos tudni, hogy a statikus metódusok fordítási időben kapcsolódnak, ellentétben a virtuális vagy nem statikus metódusok összekapcsolásával, amelyek futási időben kapcsolódnak, amikor egy valós objektumra hívják őket. Ennek megfelelően a statikus metódusokat nem lehet felülírni a Java-ban, mivel a polimorfizmus nem vonatkozik rájuk futási időben. Ez egy fontos korlátozás, amelyet figyelembe kell venni, amikor egy metódust statikusnak nyilvánítunk. Ennek csak akkor van értelme, ha nincs lehetőség vagy szükség a metódus felülbírálására egy alosztályban. A gyári módszerek és a hasznossági módszerek jó példái a statikus módosító helyes használatának. Joshua Bloch számos előnyére hívja fel a figyelmet, amelyekkel a statikus gyári módszerek rendelkeznek a konstruktorokkal szemben az Effective Java című könyvében, amely minden Java programozó számára kötelező.
-
Az inicializálás a statikus blokk egyik fontos szempontja. A statikus mezők vagy változók az osztály memóriába való betöltése után inicializálódnak. Az inicializálás sorrendje fentről lefelé, ugyanabban a sorrendben, ahogyan a Java osztály forrásfájljában deklarálva vannak. Mivel a statikus mezők inicializálása szálbiztos módon történik, ezt a folyamatot a
Singleton
minta megvalósítására is használják. Ha valamilyen okból nem használ egyetEnum
,Singleton
akkor van egy jó alternatíva. De ebben az esetben figyelembe kell vennie, hogy ez nem "lusta" inicializálás. Ez azt jelenti, hogy a statikus mezőt még MIELŐTT inicializálják, mielőtt valaki "kérné". Ha egy objektum sok erőforrást igényel, vagy ritkán használják, akkor statikus blokkban történő inicializálása nem fog az Ön javára. -
A szerializálás során a statikus mezők, akárcsak
transient
a változók, nem kerülnek sorba. Valójában, ha bármilyen adatot elment egy statikus mezőbe, az a deserializálás után tartalmazza a kezdeti (alapértelmezett) értékét. Például, ha egy statikus mező egyint
, akkor értéke nulla lesz a deszerializálás után. Ha típusafloat
, akkor az értéke 0,0 lesz. Ha a mező egyObject
, akkor az értékenull
. Hogy őszinte legyek, ez az egyik leggyakrabban feltett kérdés a sorozatosítással kapcsolatban a Java-pozíciókkal kapcsolatos interjúkban. Ne tároljon lényeges objektumadatokat statikus mezőben! -
Végül beszéljünk a statikus importról. Ez a módosító sok hasonlóságot mutat a standard
import
utasítással, de abban különbözik, hogy lehetővé teszi egy vagy az összes statikus osztálytag importálását. A statikus metódusok importálása után úgy érhetők el, mintha ugyanabban az osztályban lennének deklarálva. Hasonlóképpen, statikus mezők importálásával az osztálynév megadása nélkül érhetjük el őket. Ez a funkció a Java 1.5-ben jelent meg, és megfelelő használat esetén javítja a kód olvashatóságát. Ez a konstrukció leggyakrabban a JUnit tesztekben található meg, mivel szinte minden tesztfejlesztő statikus importot használ az assert metódusokhoz, pl.assertEquals()
és túlterhelt változataihoz. -
Ez minden most. Minden Java programozónak ismernie kell a fent említett statikus módosító összes szempontját. Ez a cikk a statikus változókkal, mezőkkel, metódusokkal, inicializálási blokkokkal és importálással kapcsolatos alapvető információkat tekinti át. Kitért néhány fontos tulajdonságra is, amelyek ismerete elengedhetetlen a Java programok írásához és megértéséhez. Remélem, hogy minden fejlesztő tökéletesíteni fogja a statikus tagok ügyes használatát, mert ez nagyon fontos a komoly szoftverfejlesztéshez."
GO TO FULL VERSION