Gyakorlati alapok III.
A getter-setter függvények
This one, please! - a this referencia
Az előző, Get it and set it! című fejezetben a getter-setter függvények funkcionalitását tanulmányozhattuk. Bevezetésképpen ismételjük meg az egyik kódot:
public class Teszt{
private int szam = 2;
public Teszt(){
}
public Teszt(int szam){
this.szam = szam;
}
public int getSzam(){
return this.szam;
}
public void setSzam(int szam){
if(szam > 10 || szam < 1){
System.out.println("Nem megfelelő számbevitel!");
}
this.szam = szam;
}
}
Többször is észrevehetjük benne a this szót.
A this egy referencia, azaz egy olyan mutató, amellyel szabályozott körülmények között arra mutathatunk, amire csak akarunk.
Belátom, egy kissé esetlen a meghatározás, bár szerintem így is sokkal jobban érthető, mert a "klasszikus" definíció szerint olyan referencia, amely mindig az aktuális, jelenlegi objektumra mutat (a reference to the current object).
(Zárójelben jegyzem meg, hogy olvastam ennél hajmeresztőbb definíciót is, amely ugyan tudományos igénnyel készült, de nincs sok értelme, ha nem érti meg senki.)
A this egy virtuális mutatóujj, amellyel a rendszer által meghatározott-engedélyezett vagy éppen jelenlévő elemekre, objektumokra mutathatunk. Voltaképpen egy olyan memóriacím, amely az éppen meghívott objektum címét (referenciáját) tartalmazza.
A this használatának alapjában véve önmagában nincs sok értelme, gondoljunk csak arra, ha az "Ezt kérem! - This one, please!" felkiáltással nem mutatnánk semmire.
Később, működő kódokban látni fogjuk, hogy a JVM ezt mégis megengedi nekünk, hiszen megfelelő kódkörnyezetben már a System.out.println(this) használatakor is kapunk valamilyen eredményt. Ebben az esetben például a kódkörnyezet egy, a new paranccsal szabályosan létrehozott osztály, a this pedig az osztályból létrehozott objektumot, illetve annak bizonyos tulajdonságait mutatja meg nekünk (lásd lentebb). Ebből következően: ha van éppen futó objektum, akkor van this is, amely tehát mindig őrá, az éppen futó objektumra mutat.
Bonyolítsuk tovább a this funkcionalitását!
Valójában a this még akkor sem működőképes, ha vele konkrétan rámutatunk egy elemre (például this.szam), mert ebben az esetben sem tudja még a rendszer, hogy ezzel mit akarunk kezdeni. Következésképpen minimum egy értékadás az, amellyel kapcsolatot lehet teremteni a mutató és konkrét programelemek között (például this.szam = szam).
A probléma kódszintű megértéséhez először csupaszítsuk le a fenti kódot:
public class Teszt{
private int szam = 2;
public Teszt(int szam){
this.szam = szam;
}
}
Láthatjuk, hogy voltaképpen 2 db int szam deklaráció történt:
-
az egyik osztályszinten - private int szam = 2,
-
a másik a Teszt osztály konstruktor függvényének paraméterlistájában (public Teszt(int szam)).
Mi tudjuk, hogy ez a deklaráció ugyanarra a változóra vonatkozik -legalábbis ez a szándékunk-, ám a Java-rendszer nem és ezt felé egyértelművé kell tenni.
A Java-rendszer számára public Teszt(int szam) deklaráció elfedi, elrejti, árnyékolja a private int szam deklarációt. Ezért kell kapcsolatot létrehoznunk a 2 deklaráció között a this.szam = szam értékadással.
A this összetett használatára nézzünk meg egy másik Java-kódot. Már megszokott módon 2 osztályból, Teszt és Main osztályból áll. A Teszt osztályba illesztettünk egy printTeszt() metódust is, amelyet teletömtünk különböző elemek felé mutató this referenciákkal:
public void printTeszt() {
int szam = 6;
System.out.println(szam);
System.out.println(this.szam);
System.out.println(this);
System.out.println(this.toString);
System.out.println(this.getClass());
}
}
-
szam - ez a referencia a printTeszt() metódusban deklarált int szam változóra mutat, értéke 6,
-
this.szam - ez a referencia az osztályszinten deklarált int szam változóra mutat, értéke 2,
-
this - ez a referencia az osztály toString() metódusát hívja meg, amely a következőt adja vissza: Teszt@15db9742 - jelentése:
-
rész - az ősosztály neve,
-
rész - @ karakter,
-
rész - előjel nélküli, hexadecimális reprezentációja a Teszt osztályból keletkezett teszt objektum hasítókódjának (hash code),
-
-
this.toString() - a fentiek bizonyítására közvetlenül is meghívtam az osztály toString() metódusát, amelynek végeredménye ugyanaz lesz, mint fent: Teszt@15db9742,
this.getClass - ez a referencia az ősosztály nevét adja vissza, értéke Teszt.
Nézzük meg a futtatható Java-kódot:
public
class Teszt{
public int szam = 2;
public Teszt(){
}
public Teszt(int szam){
this.szam = szam;
}
public int getSzam(){
return this.szam;
}
public void setSzam(int szam){
if(szam > 10 || szam < 1){
System.out.println("Nem megfelelő számbevitel!");
}
this.szam = szam;
}
public void printTeszt() {
int szam = 6;
System.out.println(szam);
System.out.println(this.szam);
System.out.println(this);
System.out.println(this.toString);
System.out.println(this.getClass());
}
}
public
class Main {
public static void main(String[] args) {
Teszt teszt = new Teszt();
teszt.printTeszt();
}
}
Végeredmény:
6
2
Teszt@15db9742
Teszt@15db9742
class Teszt