1. Tulajdonságok: getterek és szetterek
Amikor egy nagy projektet egyszerre több tucat programozó fejleszt, akkor gyakran problémák merülnek fel, ha másképp kezelik az osztálymezőkben tárolt adatokat.
Lehet, hogy az emberek nem tanulmányozzák részletesen az osztály dokumentációját, vagy nem ír le minden esetet. Ennek eredményeként gyakran előfordulnak olyan helyzetek, amikor egy objektum belső adatai "sérülhetnek", ami érvénytelenné teszi az objektumot.
Az ilyen helyzetek elkerülése érdekében a Java-ban szokás minden osztálymezőt priváttá tenni . Csak az osztály metódusai módosíthatják az osztály változóit. Más osztályokból származó metódusok nem férhetnek hozzá közvetlenül a változókhoz.
Ha azt szeretné, hogy más osztályok is hozzáférhessenek vagy módosíthassanak az osztályának objektumain belüli adatokat, két metódust kell hozzáadnia az osztályhoz – egy get metódust és egy set metódust. Példa:
Kód | jegyzet |
---|---|
|
private név mező A mező inicializálása a konstruktoron keresztül getName() — Ez a metódus a névmező értékét adja vissza setName() — Ez a metódus megváltoztatja a névmező értékét |
Más osztály nem tudja közvetlenül megváltoztatni a névmező értékét. Ha valakinek meg kell szereznie a név mező értékét, akkor meg kell hívnia a getName()
metódust egy Person
objektumon. Ha valamilyen kód meg akarja változtatni a névmező értékét, akkor meg kell hívnia a setName()
metódust egy Person
objektumon.
A metódust " névmező getterénekgetName()
" is nevezik , a metódust pedig " névmező beállítójának" .setName()
Ez egy nagyon elterjedt megközelítés. Az összes Java kód 80-90%-ában soha nem fogsz nyilvános változókat látni egy osztályban. Ehelyett deklarálva lesznek private
(vagy protected
), és minden változónak nyilvános getterei és beállítói lesznek.
Ez a megközelítés hosszabb, de megbízhatóbbá teszi a kódot.
Az osztályváltozók közvetlen elérése olyan, mintha dupla sárga vonalon átfordítaná az autót : könnyebb és gyorsabb, de ha mindenki megteszi, akkor mindenki számára rosszabb lesz a helyzet.
Tegyük fel, hogy szeretne létrehozni egy osztályt, amely leír egy pontot ( x
, y
). Íme, hogyan csinálná egy kezdő programozó:
class Point
{
public int x;
public int y;
}
Íme, hogyan csinálná egy tapasztalt Java programozó:
Kód |
---|
|
Hosszabb a kód? Kétségtelenül.
De hozzáadhat paraméterellenőrzést a getterekhez és a beállítókhoz. Például megbizonyosodhat arról, hogy x
és y
értéke mindig nagyobb, mint nulla (vagy nem kisebb nullánál). Példa:
Kód | jegyzet |
---|---|
|
2. Az objektum élettartama
Már tudja, hogy az objektumok az new
operátor segítségével jönnek létre, de hogyan törlődnek az objektumok? Nem léteznek örökké. Nincs elég memória ehhez.
Számos programozási nyelvben, például a C++-ban, létezik egy speciális delete
operátor az objektumok törlésére. De hogyan működik ez a Java-ban?
A Java nyelven minden kicsit másképp van elrendezve. A Java-nak nincs delete operátora. Ez azt jelenti, hogy a Java-ban nem törlődnek az objektumok? Nem, természetesen törölve vannak. Ellenkező esetben a Java alkalmazásokból gyorsan elfogyna a memória, és szó sem lehet arról, hogy a programok hónapokig megszakítás nélkül futnak.
Java nyelven az objektumok törlése teljesen automatizált. A Java gép maga kezeli az objektumok törlését. Ezt a folyamatot szemétgyűjtésnek, a szemetet gyűjtő mechanizmust pedig szemétgyűjtőnek ( GC ) nevezik .
Tehát honnan tudja a Java gép, hogy mikor kell törölnie egy objektumot?
A szemétgyűjtő minden tárgyat "elérhető" és "elérhetetlen" részekre oszt. Ha van legalább egy hivatkozás egy objektumra, akkor az elérhetőnek minősül. Ha nincs olyan változó, amely egy objektumra hivatkozik, akkor az objektumot elérhetetlennek tekintik, és szemétnek nyilvánítják, ami azt jelenti, hogy törölhető.
Java nyelven nem hozhat létre hivatkozást egy meglévő objektumhoz – csak a már meglévő hivatkozásokat rendelheti hozzá. Ha törölünk minden hivatkozást egy objektumra, akkor az örökre elveszik.
Körhivatkozások
Ez a logika jól hangzik egészen addig, amíg nem találunk egy egyszerű ellenpéldát: tegyük fel, hogy van két objektumunk, amelyek egymásra hivatkoznak (egymásra utaló hivatkozásokat tárolunk). Más objektumok nem tárolnak hivatkozásokat ezekre az objektumokra.
Ezek az objektumok nem érhetők el a kódból, de továbbra is hivatkoznak rájuk.
Ez az oka annak, hogy a szemétgyűjtő felosztja a tárgyakat elérhetőre és elérhetetlenre, ahelyett, hogy "hivatkozott" és "nem hivatkozott".
Elérhető tárgyak
Először a 100%-ban élő objektumok kerülnek az elérhető listára. Például az aktuális szál ( Thread.current()
) vagy a konzol InputStream ( System.in
).
Ezután az elérhető objektumok listája kibővül olyan objektumokkal, amelyekre az elérhető objektumok kezdeti készlete hivatkozik. Ezután ismét kibővül, hogy tartalmazza azokat az objektumokat, amelyekre ez a kinagyított halmaz hivatkozik, és így tovább.
Ez azt jelenti, hogy ha vannak olyan objektumok, amelyek csak egymásra hivatkoznak, de az elérhető objektumokról nem lehet elérni őket, akkor ezek az objektumok szemétnek minősülnek, és törlődnek.
3. Szemétgyűjtés
Az emlékezet töredezettsége
Az objektumtörléssel kapcsolatos másik fontos pont a memória töredezettsége. Ha folyamatosan hoz létre és töröl objektumokat, a memória hamarosan erősen töredezett lesz: a foglalt memóriaterületeket a nem foglalt memóriaterületekkel tarkítják.
Emiatt könnyen kerülhetünk olyan helyzetbe, hogy nem tudunk nagy objektumot létrehozni (például millió elemű tömböt), mert nincs egy nagy darab szabad memória. Más szavakkal, lehet, hogy van szabad memória, akár sok is, de lehet, hogy nincs nagy összefüggő szabad memóriablokk.
Memória optimalizálás (töredezettségmentesítés)
A Java gép ezt a problémát sajátos módon oldja meg. Valahogy így néz ki:
A memória két részre oszlik. Minden objektum létrehozása (és törlése) csak a memória felében történik. Amikor eljön az idő, hogy kitisztítsuk a memória lyukait, az első felében lévő összes objektumot a rendszer átmásolja a második felébe. De közvetlenül egymás mellé vannak másolva, hogy ne legyenek lyukak.
A folyamat nagyjából így néz ki:
1. lépés: Az objektumok létrehozása után
2. lépés: "lyukak" megjelenése
3. lépés: A "lyukak" megszüntetése
És ezért nem kell objektumokat törölnie. A Java gép egyszerűen átmásolja az összes elérhető objektumot egy új helyre, és felszabadítja a teljes memóriaterületet, ahol az objektumokat korábban tárolták.
GO TO FULL VERSION