Java Reflection. Reflexió a Java nyelvben

Hasonló dokumentumok
Önelemzés és a JavaBean komponensmodell

OOP: Java 8.Gy: Abstract osztályok, interfészek

Helyes-e az alábbi kódrészlet? int i = 1; i = i * 3 + 1; int j; j = i + 1; Nem. Igen. Hányféleképpen lehet Javaban megjegyzést írni?

JAVA PROGRAMOZÁS 2.ELŐADÁS

Programozási nyelvek Java

Objektumorientált programozás C# nyelven

Programozás I. 5. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Smalltalk 3. Osztályok létrehozása. Készítette: Szabó Éva

Java programozási nyelv 4. rész Osztályok II.

Programozási nyelvek Java

Java programozási nyelv 6. rész Java a gyakorlatban

Bevezetés a Python programozási nyelvbe

Java II. I A Java programozási nyelv alapelemei

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

JUnit. JUnit használata. IDE támogatás. Parancssori használat. Teszt készítése. Teszt készítése

JAVA PROGRAMOZÁS 3.ELŐADÁS

Java programozási nyelv 5. rész Osztályok III.

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

C#, OOP. Osztályok tervezése C#-ban

Osztályok. 4. gyakorlat

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Programozás I. Első ZH segédlet

Programozási nyelvek Java

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

Programozás III CSOMAGOK. Az összetartozó osztályok és interfészek egy csomagba (package) kerülnek.

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

és az instanceof operátor

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Programozási nyelvek Java

3. Gyakorlat Ismerkedés a Java nyelvvel

Széchenyi István Egyetem. Programozás III. Varjasi Norbert

Java II. I A Java programozási nyelv alapelemei

Szoftvertechnológia alapjai Java előadások

OOP: Java 4.Gy: Java osztályok

ELTE SAP Excellence Center Oktatóanyag 1

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

Programozási nyelvek II. JAVA EA+GY 1. gyakolat

Java osztálykönyvtár és használata

Java programozási nyelv 7. rész Java osztálykönyvtár 1.

Programozási nyelvek Java


Segédanyag: Java alkalmazások gyakorlat

Programozás BMEKOKAA146. Dr. Bécsi Tamás 7. előadás

OOP #14 (referencia-elv)

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

Web-technológia PHP-vel

Segédanyag: Java alkalmazások gyakorlat

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Programozási nyelvek II.: JAVA, 3. gyakorlat

1. Jelölje meg az összes igaz állítást a következők közül!

Java bevezet o Kab odi L aszl o Kab odi L aszl o Java bevezet o

Programozási nyelvek II.: JAVA

Java programozási nyelv

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 2.ELŐADÁS. Objektumorientált programozás

Programozási nyelvek II.: JAVA

Objektumorientált programozás C# nyelven

Szervlet-JSP együttműködés

Programozási technológia I.

OOP: Java 6.Gy: Java osztályok. Definíció, static, túlterhelés

C# osztályok. Krizsán Zoltán

Java és web programozás

III. OOP (objektumok, osztályok)

Programozás III KIINDULÁS. Különböző sportoló típusok vannak: futó, magasugró, focista, akik teljesítményét más-más módon határozzuk meg.

OOP: Java 8.Gy: Gyakorlás

Programozási technikák Pál László. Sapientia EMTE, Csíkszereda, 2009/2010

Bevezetés, a C++ osztályok. Pere László

Programozási nyelvek II.: JAVA, 4. gyakorlat

Informatika terméktervezőknek

Programozási nyelvek JAVA EA+GY 1. gyakolat

C++ programozási nyelv Konstruktorok-destruktorok

Készítette: Nagy Tibor István

Java III. I I. Osztálydefiníció (Bevezetés)

Osztályok. construct () destruct() $b=new Book(); $b=null; unset ($b); book.php: <?php class Book { private $isbn; public $title;

Programozás II. labor

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Abstract osztályok és interface-ek. 7-dik gyakorlat

Programozási nyelvek II. JAVA

Programozás I. Objektum-orientált programozás Stringműveletek V 1.0 ÓE-NIK-AII,

Pénzügyi algoritmusok

Objektum Orientált Programozás. 5. JAVA osztályok 21/1B IT MAN

C# osztálydeníció. Krizsán Zoltán 1. .net C# technológiák tananyag objektum orientált programozás tananyag

Objektumorientált programozás C# nyelven

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

Objektumorientált programozás C# nyelven

Kivételkezelés, beágyazott osztályok. Nyolcadik gyakorlat

OOP: Java 7.Gy: Öröklődés, referenciák

Java III. I I. Osztálydefiníció (Bevezetés)

Programozási nyelvek Java

Collections. Összetett adatstruktúrák

Programozási nyelvek II.: JAVA, 11. gyakorlat

Java IX. telkezelés a Java-ban

3. Osztályok II. Programozás II

Programozási nyelvek II. JAVA

Java és web programozás

Java IX. telkezelés a Java-ban

Generikus Típusok, Kollekciók

Programozási nyelvek II.: JAVA

Átírás:

Java Reflection Reflexió a Java nyelvben 1

A Java vizsgálja a Java-t A Java egyik szokatlan képessége, hogy egy program vizsgálhatja önmagát» Meghatározhatjuk egy objektum osztályát» Mindent megtudhatunk egy osztályról: a hozzáférési módosítóit, a szülőosztályát, mezőit, konstruktorait és metódusait» Kideríthetjük, egy interfészben mi micsoda» Még ha nem is ismerjük a dolgok neveit a program megírásakor, Létrehozhatjuk egy osztály egy példányát Beállíthatunk egy lekérdezhetünk példányváltozókat Meghívhatjuk egy objektum egy metódusát Létrehozhatunk és kezelhetünk tömböket 2

Mire való a reflexió? A normális programokban nincs szükség reflexióra Akkor van szükség a reflexióra, ha programokat feldolgozó programokkal dolgozunk Jellegzetes példák:» Osztályböngésző» Debugger» GUI építő» IDE, pl. BlueJ, Netbeans vagy Eclipse» Egy hallgatói programokat osztályozó program 3

A Class osztály Hogy többet tudjunk meg egy osztályról, először a Class objektumára van szükségünk» Ha van egy obj objektumunk, a Class c = obj.getclass(); utasítással kaphatjuk meg az osztályobjektumát.» Egy c osztály szülőosztályának osztályobjektumát a Class sup = c.getsuperclass(); utasítással kaphatjuk meg.» Ha ismerjük egy osztály nevét (pl. Button) fordítási időben, a Class c = Button.class; utasítással is megkaphatjuk.» Ha tudjuk az osztály nevét futási időben (egy str String változóban), az osztályobjektumát a Class c = Class.forName(str); utasítás adja. 4

Az osztálynév lekérése Ha van egy c osztályobjektumunk, a c.getname() utasítással kaphatjuk meg az osztály nevét. A getname a teljes minősített nevet adja vissza, tehát a Class c = Button.class; String s = c.getname(); System.out.println(s); kimenete a következő lesz: java.awt.button A Class osztály és metódusai a java.lang csomagban vannak, ami mindig importálásra kerül és elérhető 5

Kérjük le az összes ősosztályt A getsuperclass() egy Class objektumot ad vissza (vagy null-t ha Object-re hívjuk meg, aminek nincs ősosztálya) A következő kód a Sun útmutatóból van: static void printsuperclasses(object o) { Class subclass = o.getclass(); Class superclass = subclass.getsuperclass(); while (superclass!= null) { String classname = superclass.getname(); System.out.println(className); subclass = superclass; superclass = subclass.getsuperclass(); } } 6

Kérjük le az osztály módosítóit I Egy Class objektum módosítói (pl. public, final, abstract, stb.) egy int-ben vannak lekódolva, és a getmodifiers() metódussal kérdezhetőek le. Az int eredmény dekódolásához a java.lang.reflect csomagban lévő Modifier osztály metódusaira van szükségünk, tehát: import java.lang.reflect.*; Ezután már csinálhatunk ilyesmi dolgokat: if (Modifier.isPublic(m)) System.out.println("public"); 7

Kérjül le az osztály módosítóit II A Modifier (többek között) a következő metódusokat tartalmazza:» public static boolean isabstract(int)» public static boolean isfinal(int)» public static boolean isinterface(int)» public static boolean isprivate(int)» public static boolean isprotected(int)» public static boolean ispublic(int)» public static String tostring(int) Ez egy ilyen típusú String-et fog visszaadni: "public final synchronized strictfp" 8

Kérjünk le interfészeket Egy osztály nulla vagy több interfészt implementálhat A getinterfaces() Class objektumok egy tömbjét adja vissza Példa: static void printinterfacenames(object o) { Class c = o.getclass(); Class[] theinterfaces = c.getinterfaces(); for (Class inf: interfaces) { System.out.println(inf.getName()); }} Jegyezzük meg, milyen előnyös a bejáró forciklus 9

Osztályok és interfészek vizsgálata A Class osztály osztályokat és interfészeket is reprezentál Ahhoz, hogy eldöntsük, egy adott Class objektum interfész-e, használjuk a c.isinterface() metódust Ha többet akarunk megtudni az osztályobjektumról, használjuk a következőket:» getmodifiers()» getfields() // mezők, azaz példányváltozók» getconstructors()» getmethods()» isarray() 10

Kérjünk le mezőket public Field[] getfields() throws SecurityException» A publikus mezők egy tömbjét adja vissza (az örökölt mezőket is beleértve).» A tömb elemszáma lehet nulla» A mezők visszaadása nem meghatározott sorrendben történik» A helyben definiált és az örökölt példányszintű változók is visszaadódnak, de a statikus változók nem. public Field getfield(string name) throws NoSuchFieldException, SecurityException» A megnevezett publikus mező adódik vissza» Ha közvetlenül nem találunk ilyen mezőt, a szülőosztályokban és interfészekben keresünk rekurzívan 11

Mezők használata I Ha f egy mező objektum, akkor» f.getname() a mező egyszerű nevét» f.gettype() a mező típusát (osztályát)» f.getmodifiers() a mező módosítóit» f.tostring() a mező hozzáférési módosítóit, típusát és teljesen minősített nevét tartalzó String-et adja vissza Példa: public java.lang.string Person.name» f.getdeclaringclass() azt az osztályt adja vissza, mellyel a mező deklarálásra került megjegyzés: a getfields() visszaadhat ősosztály mezőket is. 12

Mezők használata II Egy konkrét obj objektum mezőit a következőkkel érhetjük el:» boolean f.getboolean(obj), int f.getint(obj), double f.getdouble(obj), stb., a mező értékét adják vissza, feltételezve, hogy adott típusú, vagy az adott típusra bővíthető» Object f.get(obj) úgy annak feltételezésével adja vissza a mező értékét, hogy egy Object» void f.set(obj, value), void f.setboolean(obj, bool), void f.setint(obj, i), void f.getdouble(obj, d), stb. beállítják a mező értékét 13

Kérjük le egy osztály konstruktorait Ha c egy Class, akkor c.getconstructors() : Constructor[] alakban visszaadja a c osztály összes publikus konstruktorának egy tömbjét. c.getconstructor( Class paramtypes ) egy olyan konstruktort ad vissza, mely paramétereinek típusai egyeznek a megadott paramtypes típusokkal. Példa: String.class.getConstructors().length > 15; String.class.getConstrucor( char[].class, int.class, int.class).tostring() > String(char[], int,int). 14

Konstruktorok Ha a c egy Constructor objektum, akkor» c.getname() a konstruktor nevét adja vissza Stringként (ez megegyezik az osztály nevével)» c.getdeclaringclass() azt az osztályt (Class-t) adja vissza, melyben ez a konstruktor deklarálva lett» c.getmodifiers() a konstruktor módosítóit (Modifier-eit) adja vissza» c.getparametertypes() Class objektumok egy tömbjét adja vissza deklarációs sorrendben» c.newinstance(object initargs) létrehozza és visszaadja a c osztály egy új példányát Az olyan argumentumok, melyeknek primitív típusúnak kell lennie, szükség esetén automatikusan kicsomagolásra kerülnek 15

Példa Constructor c = String.class.getConstrucor( char[].class, int.class, int.class); c.tostring() String(char[], int,int). String s = c.newinstance( assert s == bc ; new char[] { a, b, c, d }, 1, 2 ); 16

Methods public Method[] getmethods() throws SecurityException» Method objektumok egy tömbjével tér vissza» Ezek az osztály vagy interfész publikus tag metódusai, beleértve az örökölt metódusokat» A metódusok nem meghatározott sorrendben kerülnek visszaadásra public Method getmethod(string name, Class parametertypes) throws NoSuchMethodException, SecurityException 17

Method metódusok, I getdeclaringclass()» Azt a Class objektumot adja vissza, mely reprezentálja az adott Method objektum által reprezentált metódust deklaráló osztályt vagy interfészt getname()» Az adott Method objektum által reprezentált metódus nevét adja vissza egy String formájában getmodifiers()» Az adott Method objektum által reprezentált metódus Java nyelvi módosítóit adja vissza integerként getparametertypes()» Azon Class objektumok tömbjét adja vissza deklarációs sorrendben, melyek reprezentálják az adott Method objektum által reprezentált metódus formális paramétereinek típusait 18

Method metódusok, II getreturntype()» Egy, az adott Method objektum által reprezentált metódus formális visszatérési típusát reprezentáló Class objektumot ad vissza tostring()» Egy String-et ad vissza, mely leírja a metódust (általában elég hosszú) public Object invoke(object obj, Object args)» Meghívja az adott Method objektum mögött meghúzódó metódust a megadott objektumra a megadott paraméterekkel» Az egyes paraméterek automatikusan kicsomagolásra kerülnek, hogy illeszkedjenek a primitív típusú formális paraméterekre 19

abcdefg.length() > 7 invoke() példák Method lengthmethod = String.class.getMethod( length ) ; lengthmethod.invoke( abcdefg ) > 7 abcdefg.substring(2, 5) > cde Method substringmethod = String.class.getMethod ( substring, int.class, Integer.TYPE ) ; substringmethod.invoke( abcdefg, 2, new Integer(5) ) > cde 20

Tömbök I Annak meghatározásához, hogy egy adott obj objektum tömb-e,» Kérdezzük le az osztályát, c-t: Class c = obj.getclass();» Ezt teszteljük a c.isarray() metódushívással A tömb komponenseinek típusát adja meg a» c.getcomponenttype() Ez null-t ad vissza, ha c nem egy tömb osztálya Példa:» int[].class.isarray() == true ;» int[].class.getcomponenttype() == int.class 21

Tömbök II A java.lang.reflect csomag Array osztálya statikus metódusokat biztosít ahhoz, hogy tömbökkel tudjunk dolgozni Bármilyen tömb létrehozásához: Array.newInstance(Class componenttype, int size)» Ez egy Object-et, az újonnan létrejövő tömböt adja vissza Ezt tetszőlegesen bármilyen típusra lehet kasztolni» Akár maga a componenttype is lehet egy tömb Így egy többdimenziós tömböt hoznánk létre Általában a dimenziók számának határa 255 Array.newInstance(Class componenttype, int sizes)» Ez egy Object-ként egy újonnan létrejövő többdimenziós tömböt ad vissza (sizes.length darab dimenzióval) 22

Példák A következő két objektum típusa megegyezik:» new String[10]» Array.newInstance(String.class, 10) A következő két objektum típusa megegyezik:» new String[10][20]» Array.newInstance(String.class, 10, 20) 23

Tömbök III Tömbelemek értékének kinyeréséhez» Array.get(Object array, int index) egy Object-et» Array.getBoolean(Object array, int index) egy boolean-t» Array.getByte(Object array, int index) egy byte-ot» ad vissza, és így tovább Ha pedig értékeket akarunk letárolni egy tömbben,» Array.set(Object array, int index, Object value)» Array.setInt(Object array, int index, int i)» Array.setFloat(Object array, int index, float f)» stb. 24

Példák a = new int[] {1,2,3,4}; Array.getInt(a, 2) // 3 Array.setInt(a, 3, 5 ) // a = {1,2,3, 5 }. s = new String[] { ab, bc, cd }; Array.get(s, 1 ) // bc Array.set(s, 1, xxx ) // s[1] = xxx 25

Kérjük le egy osztály nem publikus tagjait A fentebb említett Class minden getxxx() típusú metódusa csak a célosztály (és annak ősosztályainak) publikus tagjait adja vissza, de nem tudják a nem publikus tagokat visszaadni. A Class-ben létezik egy másik csoport, a getdeclaredxxx() metódusok, melyek a célosztály összes tagot (még a privát és statikus módosítójúakat is) visszaadják, az örökölt tagokat viszont nem. getdeclaredconstructors(), defdeclaredconstrucor(class ) getdeclaredfields(), getdeclaredfield(string) getdeclaredmethods(), getdeclaredmethod(string, Class ) 26

Példa String.class.getConstructors().length > 15 String.class.getDeclaredConstructors().length > 16. Constructor[] cs = String.class.getDeclaredConstructors(); for(constructor c : cs) if(! (Modifier.isPublic(c.getModifiers()))) out.println(c); > java.lang.string(int,int,char[]) // package 27

Összefoglaló megjegyzések Az említett metódusok közül sok olyan kivételeket válthat ki, melyekre itt nem tértünk ki» Részletek a Java API-ban találhatóak erről A reflexiót nem használjuk normális programokban, de amikor szükség van rá, akkor pótolhatatlan A Java reflection csomagjának tanulmányozásával lehetőség nyílik a java osztályszerkezetének áttekintésére. 28

3. Programozási feladat Írjunk egy DumpClass nevű programot, mely szépen ki tud írni egy adott típust (osztályt vagy interfészt) részletesen, a javap outputjához hasonlóan, azzal a kivétellel, hogy: Megjegyzések: 1. A kimenet első sora egy csomagdeklaráció legyen. 2. Minden, a kimenetben használt nevet importálni kell, így csak egyszerű nevek szerepelhetnek az import utasításokon kívül.» példa: a következő kimenet helyett:» public class packageofa.a {» public java.util.vector m1() }» A következő kimenetet kell kapnunk:» package packofa;» import java.util.vector;» public class A {» public java.util.vector m1() } 29