logo

Java Reflection API

Java Reflection je proces zkoumání nebo úpravy chování třídy za běhu za běhu .

The java.lang.Class třída poskytuje mnoho metod, které lze použít k získání metadat, prozkoumání a změně chování třídy za běhu.

Balíčky java.lang a java.lang.reflect poskytují třídy pro reflexi java.

Kde se používá

Reflection API se používá hlavně v:

  • IDE (Integrované vývojové prostředí), např. Eclipse, MyEclipse, NetBeans atd.
  • Debugger
  • Testovací nástroje atd.
Víš?
  • Kolika způsoby můžeme získat instanci třídy Class?
  • Jak vytvořit nástroj javap?
  • Jak vytvořit nástroj appletviewer?
  • Jak získat přístup k soukromé metodě zvenčí třídy?

třída java.lang.Class

Třída java.lang.Class plní hlavně dva úkoly:

  • poskytuje metody pro získání metadat třídy za běhu.
  • poskytuje metody pro zkoumání a změnu chování třídy za běhu.

Běžně používané metody třídy Class:

MetodaPopis
1) veřejný řetězec getName()vrátí název třídy
2) public static Class forName(String className) vyvolá výjimku ClassNotFoundExceptionnačte třídu a vrátí odkaz třídy Class.
3) veřejný objekt newInstance() vyvolá výjimku InstantiationException,IllegalAccessExceptionvytvoří novou instanci.
4) public boolean isInterface()zkontroluje, zda se jedná o rozhraní.
5) public boolean isArray();zkontroluje, zda je pole.
6) public boolean isPrimitive()kontroluje, zda je primitivní.
7) veřejná třída getSuperclass()vrátí odkaz na třídu nadtřídy.
8) public Field[] getDeclaredFields() vyvolá výjimku SecurityExceptionvrátí celkový počet polí této třídy.
9) veřejná metoda[] getDeclaredMethods() vyvolá výjimku SecurityExceptionvrátí celkový počet metod této třídy.
10) veřejný konstruktor[] getDeclaredConstructors() vyvolá výjimku zabezpečenívrátí celkový počet konstruktorů této třídy.
11) veřejná metoda getDeclaredMethod(název řetězce,třída[]parametrTypes)vyvolá výjimku NoSuchMethodException,SecurityExceptionvrátí instanci třídy metody.

Jak získat objekt třídy Class?

Existují 3 způsoby, jak získat instanci třídy Class. Jsou následující:

prioritní fronta java
  • metoda forName() třídy Class
  • getClass() metoda třídy Object
  • syntaxe .class

1) metoda forName() třídy Class

  • se používá k dynamickému načítání třídy.
  • vrátí instanci třídy Class.
  • Měl by být použit, pokud znáte plně kvalifikovaný název třídy. Toto nelze použít pro primitivní typy.

Podívejme se na jednoduchý příklad metody forName().

multithreading v Javě

Název souboru: Test.java

 class Simple{} public class Test{ public static void main(String args[]) throws Exception { Class c=Class.forName('Simple'); System.out.println(c.getName()); } } 

Výstup:

 Simple 

2) metoda getClass() třídy Object

Vrátí instanci třídy Class. Mělo by se použít, pokud znáte typ. Navíc jej lze použít s primitivy.

Název souboru: Test.java

 class Simple{} class Test{ void printName(Object obj){ Class c=obj.getClass(); System.out.println(c.getName()); } public static void main(String args[]){ Simple s=new Simple(); Test t=new Test(); t.printName(s); } } 

Výstup:

Simple 

3) Syntaxe .class

Pokud je typ dostupný, ale neexistuje žádná instance, je možné získat třídu připojením '.class' k názvu typu. Lze jej použít i pro primitivní datové typy.

Název souboru: Test.java

řetězec k itn
 class Test{ public static void main(String args[]){ Class c = boolean.class; System.out.println(c.getName()); Class c2 = Test.class; System.out.println(c2.getName()); } } 

Výstup:

 boolean Test 

Určení objektu třídy

K určení objektu třídy se používají následující metody třídy Class:

1) public boolean isInterface(): určuje, zda zadaný objekt Class představuje typ rozhraní.

2) public boolean isArray(): určuje, zda tento objekt Class představuje třídu pole.

3) public boolean isPrimitive(): určuje, zda zadaný objekt Class představuje primitivní typ.

Podívejme se na jednoduchý příklad reflexního API pro určení typu objektu.

Název souboru: Test.java

řetězec do int java
 class Simple{} interface My{} class Test{ public static void main(String args[]){ try{ Class c=Class.forName('Simple'); System.out.println(c.isInterface()); Class c2=Class.forName('My'); System.out.println(c2.isInterface()); }catch(Exception e){System.out.println(e);} } } 

Výstup:

 false true 

Klady a zápory reflexe

Java reflexe by měla být vždy používána opatrně. Zatímco odraz poskytuje mnoho výhod, má také některé nevýhody. Nejprve si proberme výhody.

Klady: Inspekce rozhraní, tříd, metod a polí za běhu je možná pomocí reflexe, a to i bez použití jejich názvů během kompilace. Je také možné volat metody, instanciovat clear nebo nastavit hodnotu polí pomocí reflexe. Pomáhá při vytváření vizuálních vývojových prostředí a třídních prohlížečů, což poskytuje pomoc vývojářům při psaní správného kódu.

Nevýhody: Pomocí odrazu lze porušit principy zapouzdření. Je možné přistupovat k soukromým metodám a polím třídy pomocí reflexe. Odrazem tak může unikat důležitá data do vnějšího světa, což je nebezpečné. Pokud například jeden přistupuje k soukromým členům třídy a nastaví jim hodnotu null, pak druhý uživatel stejné třídy může získat výjimku NullReferenceException a toto chování se neočekává.

Další nevýhodou je režie výkonu. Vzhledem k tomu, že typy v odrazu jsou řešeny dynamicky, optimalizace JVM (Java Virtual Machine) nemůže probíhat. Proto jsou operace prováděné odrazy obvykle pomalé.

Závěr

Vzhledem k výše uvedeným nevýhodám je obecně vhodné vyhnout se použití odrazu. Jde o pokročilou funkci, kterou by měli používat pouze programátoři nebo vývojáři, kteří mají dobrou znalost základů jazyka. Vždy pamatovat! Kdykoli je použita reflexe, je ohrožena bezpečnost aplikace.


Další témata kurzu Reflection API

metoda newInstance().
Pochopení nástroje javap
vytvoření nástroje javap
nástroj pro vytváření appletů
Volání soukromé metody z jiné třídy