Az építő osztály |
Múlt havi számunkban elkezdtük a dinamikus
osztálybetöltést, és bővebben megismerkedtünk a Class osztállyal, amely lehetővé teszi, hogy
objektumokat tudjunk létrehozni a nevük alapján, anélkül, hogy bármi más
információval rendelkeznénk az osztályról. Csak egyetlen bakija volt a bemutatott
módszernek: csak olyan osztályokat tudott létrehozni, amelyeknek volt
alapértelmezett (paraméter nélküli) konstruktor-függvénye.
A mostani cikk bemutatja miként lehet olyan
osztályokat létrehozni, ahol a kosntruktor-függvény
paramétereket is elvár. Ha egy picit beleböngészünk a Java API-ba, a Class osztálynál, látni fogjuk, hogy rendelkezik egy
olyan metódussal, mely a következőképpen mutat: Constructor[] getConstructors() és amint
le van írva, ez a metódus visszatérít egy tömböt, amely Constructor objektumokat
tartalmaz. Az osztályunk publikus konstruktor függvényeit. Ha az osztály
összes konstruktorát le szeretnénk kérdezni (beleértve a privát
konstruktorokat is), akkor használjuk a Constructor[] getDeclaredConstructors() metódust,
amely válogatás nélkül visszadja az összes konstruktort. Persze, jogos a kérdés, mi ez a Constructor, ha már ennyit szerepeltetjük. |
A Constructor osztály |
Ha tovább böngésszük az API dokumentációt,
megtaláljuk a Constructor osztályt, a következő magyarázó szöveggel: "A Constructor osztály információt szolgáltat egy osztály egy konstruktor függvényéről." A leglényegesebb, hogy a Constructor osztály a java.lang.reflect csomagban található. Ne feledjük beimportálni. Kutakodjunk tovább a Constructor osztály metódusai közt, aminek eredményeként megleljük
a Class [] getParameterTypes() metódust, mellyel lekérdezhetjük ennek
a konstruktor
függvénynek a paramétereit, amelyeket
elvár. Vigyázzunk viszont ezzel a metódussal, mert nagyon könnyen végtelen
ciklusba kerülhetünk, ha automatikusan próbáljuk elvégeztetni a feladatot. És most jön a lényeg, az Object newInstance(Object[] arguments) metódus. Mint ahogy a paramétertípus
kéri, létre kell hoznunk egy tömböt, amely tartalmazza azokat az
objektumokat, melyeket át szeretnénk adni az osztálynak, hogy azok alapján
hozza létre az új objektumot. A newInstance metódusnál a következőkre kell figyelnünk:
Van viszont egy kis probléma a
primitív típusokkal (int, float). Ezek nem igazán objektumok, mégis egy Object[] tömbbe kell berakni őket. A megoldás az, hogy
használjuk a primitív típus wrapper
osztályát (pl. az int-nek az Integer). Sikertelen
konverzió esetén megint egy IllegalArgumentExceptionnal
találjuk szembe magunkat. Ha a konstruktor
a maga során dob egy kivételt, akkor a newInstance metódus egy InvocationTargetException kivételt dob, amelynek átadja a dobott kivételt. És végül nézzük a következő
példát: import java.lang.reflect.*; //kell a Constructornak class Test { public Test(String arg1, int arg2) { System.out.println(arg1+" "+arg2); } } public class Default { public static void main(String[] args) { try { Class test
= Class.forName("Test"); Constructor cons[] = test.getDeclaredConstructors(); String a = "Hello Constructor"; int
b=2; Object paras[] = {a,new Integer(b)}; Test
testClass = (Test)(cons[0].newInstance(paras)); } catch(Exception ex) { ex.printStackTrace(); } } } Kísérletezgessünk bátran az itt bemutatott
kódrészlettel, hisz bántódásunk nem eshet. Legközelebb más lesz a napi menün. |
Deák Ferenc |