java reflection tutorial with examples
Tento videonávod vysvětluje, co je reflexe a jak ji implementovat pomocí rozhraní Reflection API:
Reflect in Java is to inspect and change the behavior of a program at runtime.
S pomocí tohoto reflexního rozhraní API můžete za běhu kontrolovat třídy, konstruktory, modifikátory, pole, metody a rozhraní. Například, můžete získat název třídy nebo podrobnosti soukromých členů třídy.
Přečtěte si celý náš Série školení JAVA pro více informací o konceptech Java.
Zde je videonávod k reflexi prostředí Java:
Co se naučíte:
Odraz v Javě
Jsme si vědomi, že v dané třídě můžeme upravit její vlastnosti a metody v době kompilace a je velmi snadné to udělat. Ať už jsou vlastnosti a metody anonymní nebo mají názvy, lze je během kompilace libovolně změnit.
Tyto třídy, metody nebo pole však za běhu nemůžeme změnit. Jinými slovy, je velmi obtížné změnit chování různých programovacích komponent za běhu, zejména u neznámých objektů.
Programovací jazyk Java poskytuje funkci nazvanou 'Odraz' což nám umožňuje upravit běhové chování třídy, pole nebo metody za běhu.
Reflexi lze tedy definovat jako a „Technika kontroly a úpravy běhového chování neznámého objektu za běhu. Objektem může být třída, pole nebo metoda. “
Reflection je „Application Programming Interface“ (API) poskytované společností Java.
Proces „Reflexe“ je zobrazen níže.
Ve výše uvedené reprezentaci vidíme, že máme neznámý objekt. Pak na tomto objektu použijeme Reflection API. Ve výsledku můžeme upravit chování tohoto objektu za běhu.
Proto můžeme v našich programech používat Reflection API za účelem úpravy chování objektu. Objekty mohou být cokoli jako metody, rozhraní, třídy atd. Tyto objekty zkontrolujeme a poté změníme jejich chování za běhu pomocí reflexního API.
V Javě jsou „java.lang“ a „java.lang.reflect“ dva balíčky, které poskytují třídy pro reflexi. Speciální třída „java.lang.Class“ poskytuje metody a vlastnosti pro extrakci metadat, pomocí kterých můžeme kontrolovat a upravovat chování třídy.
K úpravě třídy a jejích členů včetně polí, metod, konstruktorů atd. Za běhu používáme Reflection API poskytované výše uvedenými balíčky. Charakteristickým rysem Reflection API je, že můžeme manipulovat také se soukromými datovými členy nebo metodami třídy.
Reflection API se používá hlavně v:
- Reflection se používá hlavně v ladicích nástrojích, JUnit a frameworkech ke kontrole a změně chování za běhu.
- IDE (Integrated Development Environment) Např. Eclipse IDE, NetBeans atd.
- Testovací nástroje atd.
- Používá se, když má vaše aplikace knihovny třetích stran a když chcete vědět o dostupných třídách a metodách.
Reflexní API v Javě
Pomocí Reflection API můžeme implementovat reflexi na následující entity:
- Pole : Třída Field obsahuje informace, které používáme k deklaraci proměnné nebo pole, jako je datový typ (int, double, String atd.), Modifikátor přístupu (soukromý, veřejný, chráněný atd.), Jméno (identifikátor) a hodnota.
- Metoda : Třída Method nám může pomoci extrahovat informace, jako je modifikátor přístupu metody, návratový typ metody, název metody, typy parametrů metody a typy výjimek vyvolané metodou.
- Stavitel : Třída konstruktoru poskytuje informace o konstruktoru třídy, který zahrnuje modifikátor přístupu konstruktoru, název konstruktoru a typy parametrů.
- Upravit : Třída modifikátoru nám poskytuje informace o konkrétním modifikátoru přístupu.
Všechny výše uvedené třídy jsou součástí balíčku java.lang.reflect. Dále budeme diskutovat o každé z těchto tříd a pomocí příkladů programování předvedeme reflexi o těchto třídách.
Nejprve začneme třídou java.lang.Class.
třída java.lang.Class
Třída java.lang. Třída uchovává všechny informace a data o třídách a objektech za běhu. Toto je hlavní třída používaná k reflexi.
Třída java.lang.Class poskytuje:
- Metody načtení metadat třídy za běhu.
- Metody ke kontrole a úpravě chování třídy za běhu.
Vytvořte objekty java.lang.Class
Můžeme vytvářet objekty java.lang.Class pomocí jedné z následujících možností.
nejlepší software pro údržbu systému pro Windows 10
# 1) .třída rozšíření
První možností, jak vytvořit objekt třídy, je použití rozšíření .class.
Například,pokud Test je třída, můžeme vytvořit objekt třídy následujícím způsobem:
Class obj_test = Test.class;
Pak můžeme použít obj_test k provedení reflexe, protože tento objekt bude mít všechny informace o třídě Test.
# 2) metoda forName ()
Metoda forName () přebírá název třídy jako argument a vrací objekt Class.
Například,objekt třídy Test lze vytvořit takto:
class obj_test = Class.forName (“Test”);
# 3) metoda getClas ()
Metoda getClass () používá objekt třídy k získání objektu java.lang.Class.
Například,zvažte následující část kódu:
Test obj = new Test (); Class obj_test = obj.getClass ();
V prvním řádku jsme vytvořili objekt třídy Test. Pak jsme pomocí tohoto objektu nazvali metodu „getClass ()“, abychom získali objekt obj_test java.lang.Class.
Získejte Super Class & Modifikátory přístupu
java.lang.class poskytuje metodu „getSuperClass ()“, která se používá k získání nadtřídy jakékoli třídy.
Podobně poskytuje metodu getModifier (), která vrací modifikátor přístupu třídy.
Následující příklad ukazuje metodu getSuperClass ().
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println('I am a Student'); } } class Main { public static void main(String() args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println('Superclass of Student Class: ' + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }
Výstup
Ve výše uvedeném příkladu programování je rozhraní Osoba definováno osamělou metodou „display ()“. Poté definujeme třídu Student implementující rozhraní osoby. V hlavní metodě použijeme metodu getClass () k načtení objektu Class a následnému přístupu k nadřazené nebo nadtřídě Studentova objektu pomocí metody getSuperClass ().
Získejte rozhraní
Pokud třída implementuje některá rozhraní, můžeme tyto názvy rozhraní získat pomocí metody getInterfaces () metody java.lang.Class. K tomu musíme provést reflexi třídy Java.
Níže uvedený příklad programování znázorňuje použití metody getInterfaces () v prostředí Java Reflection.
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println('This is a PetAnimal::Dog'); } //define interface method makeSound public void makeSound() { System.out.println('Dog makes sound::Bark bark'); } } class Main { public static void main(String() args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class() objInterface = obj.getInterfaces(); System.out.println('Class Dog implements following interfaces:'); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println('Interface Name: ' + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }
Výstup
Ve výše uvedeném programu jsme definovali dvě rozhraní, tj. Zvířata a PetAnimals. Poté definujeme třídu Dog, která implementuje obě tato rozhraní.
V hlavní metodě načteme objekt třídy Dog v java.lang.Class, abychom provedli reflexi. Potom použijeme metodu getInterfaces () k načtení rozhraní, která jsou implementována třídou Dog.
Reflexe: Získejte hodnotu pole
Jak již bylo zmíněno, balíček java.lang.reflect poskytuje třídu Field, která nám pomáhá odrážet pole nebo datové členy třídy.
Níže jsou uvedeny metody poskytované třídou Field pro reflexi pole.
Metoda | Popis |
---|---|
getField ('fieldName') | Vrátí pole (veřejné) se zadaným názvem pole. |
getFields () | Vrátí všechna veřejná pole (jak pro třídu, tak pro nadtřídu). |
getDeclaredFields () | Načte všechna pole třídy. |
getModifier () | Vrátí celočíselnou reprezentaci modifikátoru přístupu k poli. |
set (classObject, value) | Přiřadí pole zadanou hodnotu. |
get (classObject) | Načte hodnotu pole. |
setAccessible (boolean) | Zpřístupněte soukromé pole předáním true. |
getDeclaredField ('fieldName') | Vrátí pole se zadaným názvem. |
Níže jsou uvedeny dva příklady reflexe, které demonstrují reflexi ve veřejné a soukromé oblasti.
Níže uvedený program Java demonstruje reflexi na veřejném poli.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String() args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField('StudentName'); System.out.println('Details of StudentName class field:'); // set the value of field student_field.set(student, 'Lacey'); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println('StudentName Modifier::' + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println('StudentName Value::' + typeValue); } catch(Exception e) { e.printStackTrace(); } } }
Výstup
V tomto programu jsme deklarovali třídu „Student“ s veřejným polem StudentName. Poté pomocí rozhraní API třídy Field provedeme reflexi pole StudentName a načteme jeho modifikátor a hodnotu přístupu.
Další program provede reflexi na soukromém poli třídy. Operace jsou podobné, kromě toho, že pro soukromé pole je provedeno jedno volání další funkce. Pro soukromé pole musíme zavolat setAccessible (true). Poté provedeme reflexi na toto pole podobným způsobem jako na veřejném poli.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String() args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField('rollNo'); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, '27'); System.out.println('Field Information of rollNo:'); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println('rollNo modifier::' + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println('rollNo Value::' + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }
Výstup
Reflexe: Metoda
Podobně jako pole třídy můžeme také provádět reflexi metod třídy a upravit jejich chování za běhu. K tomu používáme třídu Method balíčku java.lang.reflect.
Níže jsou uvedeny funkce poskytované metodou třídy pro reflexi metody třídy.
Metoda | Popis |
---|---|
getMethods () | Načte všechny veřejné metody definované ve třídě a její nadtřídě. |
getDeclaredMethod () | Vrátí metody deklarované ve třídě. |
getName () | Vrátí názvy metod. |
getModifiers () | Vrátí celočíselnou reprezentaci modifikátoru přístupu metody. |
getReturnType () | Vrátí návratový typ metody. |
Níže uvedený příklad ukazuje odraz třídních metod v Javě pomocí výše uvedených API.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println('I am a Vehicle!!'); } protected void start() { System.out.println('Vehicle Started!!!'); } protected void stop() { System.out.println('Vehicle Stopped!!!'); } private void serviceVehicle() { System.out.println('Vehicle serviced!!'); } }class Main { public static void main(String() args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method() methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println('Method Name: ' + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print('Modifier: ' + Modifier.toString(modifier) + ' '); // get the return type of method System.out.print('Return Type: ' + m.getReturnType()); System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Výstup
Ve výše uvedeném programu vidíme, že metoda getDeclaredMethods vrací pole metod deklarovaných třídou. Poté iterujeme tímto polem a zobrazíme informace o každé metodě.
Odraz: Konstruktor
Můžeme použít třídu „Constructor“ balíčku java.lang.reflect ke kontrole a úpravám konstruktorů třídy Java.
Třída konstruktoru pro tento účel poskytuje následující metody.
Metoda | Popis |
---|---|
getConstructors () | Vrátí všechny konstruktory deklarované ve třídě a její nadtřídě. |
getDeclaredConstructor () | Vrátí všechny deklarované konstruktory. |
getName () | Načte název konstruktoru. |
getModifiers () | Vrátí celočíselnou reprezentaci modifikátoru přístupu konstruktorů. |
getParameterCount () | Vrátí celkový počet parametrů pro konstruktory. |
Níže uvedený příklad reflexe ukazuje odraz konstruktorů třídy v Javě. Stejně jako reflexe metody zde také metoda getDeclaredConstructors vrací pole konstruktorů pro třídu. Poté procházíme tímto polem konstruktoru, abychom zobrazili informace o každém konstruktoru.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String() args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor() constructors = obj.getDeclaredConstructors(); System.out.println('Constructors for Person Class:'); for(Constructor c : constructors) { // get names of constructors System.out.println('Constructor Name: ' + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ('Modifier: ' + Modifier.toString(modifier) + ' '); // get the number of parameters in constructors System.out.println('Parameters: ' + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class() paramList=c.getParameterTypes(); System.out.print ('Constructor parameter types :'); for (Class class1 : paramList) { System.out.print(class1.getName() +' '); } } System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Výstup
Nevýhody odrazu
Reflexe je silná, ale neměla by být používána bez rozdílu. Pokud je možné pracovat bez použití odrazu, je lepší se jeho použití vyhnout.
Níže je uvedeno několik nevýhod Reflection:
- Režijní výkon: I když je reflexe výkonnou funkcí, reflexní operace mají stále pomalejší výkon než nereflexní operace. Proto bychom se měli vyhnout používání odrazů v aplikacích kritických z hlediska výkonu.
- Bezpečnostní omezení: Protože reflexe je runtime funkce, může vyžadovat oprávnění za běhu. Takže pro aplikace, které vyžadují spuštění kódu v omezeném nastavení zabezpečení, může být reflexe k ničemu.
- Expozice interních: Použitím reflexe můžeme přistupovat k soukromým polím a metodám ve třídě. Reflexe tedy rozbíjí abstrakci, která by mohla způsobit, že kód bude nepřenosný a nefunkční.
Často kladené otázky
Otázka 1) Proč se v Javě používá Reflection?
Odpovědět: Pomocí reflexe můžeme kontrolovat třídy, rozhraní, konstruktory, pole a metody za běhu, i když jsou v době kompilace anonymní. Tato kontrola nám umožňuje upravit chování těchto entit za běhu.
Otázka č. 2) Kde se používá Reflection?
Odpovědět: Reflexe se používá při psaní rámců, které spolupracují s uživatelem definovanými třídami, přičemž programátor ani neví, jaké třídy nebo jiné entity budou.
Otázka č. 3) Je Java Reflection pomalý?
Odpovědět: Ano, je to pomalejší než nereflexní kód.
Otázka č. 4) Je Java Reflection špatný?
Odpovědět: Svým způsobem ano. Nejprve ztrácíme bezpečnost při kompilaci. Bez bezpečnosti při kompilaci bychom mohli dostat chyby za běhu, které mohou ovlivnit koncové uživatele. Bude také obtížné ladit chybu.
Otázka č. 5) Jak zastavíte odraz v Javě?
Odpovědět: Jednoduše se vyhýbáme používání reflexe psaním nereflexních operací. Nebo možná můžeme použít některé obecné mechanismy, jako je vlastní ověření s odrazem.
Více o Java Reflection
Balíček java.lang.reflect obsahuje třídy a rozhraní pro reflexi. A java.lang.class lze použít jako vstupní bod pro reflexi.
Jak získat objekty třídy:
1. Pokud máte instanci objektu,
třída c = obj.getclass ();
2. Pokud znáte typ třídy,
třída c = type.getClass ();
3. Pokud znáte název třídy,
Class c = Class.forName („com.demo.Mydemoclass“);
Jak získat členy třídy:
Členy třídy jsou pole (proměnné třídy) a metody.
- getFields () - Slouží k získání všech polí kromě soukromých polí.
- getDeclaredField () - Slouží k získání soukromých polí.
- getDeclaredFields () - Slouží k získání soukromého a veřejného pole.
- getMethods () - Používá se k získání všech metod kromě soukromých metod.
- getDeclaredMethods () –Používá se k získání veřejných a soukromých metod.
Demo programy:
ReflectionHelper.java:
Toto je třída, kde budeme kontrolovat pomocí reflexního API.
Šířka prvního vyhledávání v C ++
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
ReflectionDemo.java
public class ReflectionDemo { public static void main(String() args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println('className=='+className); System.out.println('getModifiers'+ReflectionHelperclass.getModifier s()); System.out.println('getSuperclass'+ReflectionHelperclass.getSupercla ss()); System.out.println('getPackage'+ReflectionHelperclass.getPackage()); Field() fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println('only the public fieldnames:::::'+fieldname); } //getting all the fields of the class Field() privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println('all the fieldnames in the class:::'+fieldname); } Method() methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println('methods::::'+m.getName()); } }}
Závěr
Tento kurz podrobně vysvětlil Reflection API v Javě. Viděli jsme, jak provádět reflexi tříd, rozhraní, polí, metod a konstruktorů spolu s několika nevýhodami reflexe.
Reflexe je v Javě relativně pokročilou funkcí, ale měli by ji používat programátoři, kteří mají v daném jazyce pevnou pozici. Důvodem je, že pokud nebude používán opatrně, může způsobit neočekávané chyby a výsledky.
I když je odraz silný, měl by být používán opatrně. Nicméně pomocí reflexe můžeme vyvinout aplikace, které do runtime nevědí o třídách a jiných entitách.
=> Prohlédněte si příručku Java Beginners Guide zde.
Doporučené čtení
- Výukový program třídy skeneru Java s příklady
- Celé číslo Java a třída Java BigInteger s příklady
- Výukový program JAVA pro začátečníky: 100+ praktických výukových programů Java Video
- Úvod do programovacího jazyka Java - výukový program
- Co je Java Vector | Výukový program Java Vector Class s příklady
- Výukový program pro rozhraní Java a abstrakt třídy s příklady
- Metoda Java substring () - výuka s příklady
- Výukový program Java Collections Framework (JCF)