Java Reflection API-zelfstudie met voorbeeld
Wat is reflectie in Java?
Java Reflectie is het proces waarbij alle mogelijkheden van een klasse tijdens runtime worden geanalyseerd en gewijzigd. Reflectie-API in Java wordt gebruikt om de klasse en zijn leden, waaronder velden, methoden, constructor, enz., tijdens runtime te manipuleren.
Een voordeel van reflectie-API in Java dat wil zeggen dat het ook privéleden van de klas kan manipuleren.
Het pakket java.lang.reflect biedt veel klassen om reflectie-java te implementeren. Methoden van de klasse java.lang.Class worden gebruikt om de volledige metagegevens van een bepaalde klasse te verzamelen.
Klasse in java.lang.reflect-pakket
Hieronder volgt een lijst van divers Java klassen in java.lang.package om reflectie te implementeren
- Veld: Deze klasse wordt gebruikt om declaratieve informatie te verzamelen, zoals datatype, toegangsmodifier, naam en waarde van een variabele.
- Methode: Deze klasse wordt gebruikt om declaratieve informatie te verzamelen, zoals toegangsmodificator, retourtype, naam, parametertypen en uitzonderingstype van een methode.
- Constructeur: Deze klasse wordt gebruikt om declaratieve informatie te verzamelen, zoals toegangsmodificator, naam en parametertypen van een constructor.
- modifier: deze klasse wordt gebruikt om informatie te verzamelen over een bepaalde toegangsmodificator.
Methoden gebruikt in java.lang.Class
- Openbare tekenreeks getName (): Retourneert de naam van de klasse.
- openbare klasse getSuperclass(): Retourneert de superklassereferentie
- Openbare klasse[] getInterfaces() : Retourneert een array van interfaces die door de opgegeven klasse zijn geïmplementeerd
-
Openbaar in getModifiers (): Retourneert een geheel getalwaarde die de modificatoren van de opgegeven klasse vertegenwoordigt en die als parameter moet worden doorgegeven aan “openbare statische String toString (int i )” methode die de toegangsspecificatie voor de gegeven klasse retourneert.
Hoe u volledige informatie over een klas kunt krijgen
public class Guru99ClassObjectCreation { public static void main (String[] args) throws ClassNotFoundException { //1 - By using Class.forname() method Class c1 = Class.forName("Guru99ClassObjectCreation"); //2- By using getClass() method Guru99ClassObjectCreation guru99Obj = new Guru99ClassObjectCreation(); Class c2 = guru99Obj.getClass(); //3- By using .class Class c3= Guru99ClassObjectCreation.class; } }
Voorbeeld 1: Metagegevens van klasse verkrijgen
Het volgende voorbeeld laat zien hoe u metagegevens kunt ophalen, zoals de klassenaam, de naam van de superklasse, geïmplementeerde interfaces en toegangsmodifiers van een klasse.
We krijgen de metadata van onderstaande klasse genaamd Guru99Base.class:
import java.io.Serializable; public abstract class Guru99Base implements Serializable,Cloneable { }
- De naam van de klasse is: Guru99Base
- De toegangsmodificatoren zijn: openbaar en abstract
- Het heeft interfaces geïmplementeerd: serialiseerbaar en kloonbaar
- Omdat er geen enkele klasse expliciet is uitgebreid, is de superklasse: java.lang.Object
De onderstaande klasse haalt de metagegevens van Guru99Base.class op en drukt deze af:
import java.lang.reflect.Modifier; public class Guru99GetclassMetaData { public static void main (String [] args) throws ClassNotFoundException { // Create Class object for Guru99Base.class Classguru99ClassObj = Guru99Base.class; // Print name of the class system.out.println("Name of the class is : " +guru99ClassObj.getName()); // Print Super class name system.out.println("Name of the super class is : " +guru99ClassObj.getSuperclass().getName()); // Get the list of implemented interfaces in the form of Class array using getInterface() method class[] guru99InterfaceList = guru99classObj.getInterfaces(); // Print the implemented interfaces using foreach loop system.out.print("Implemented interfaces are : "); for (Class guru99class1 : quru99 InterfaceList) { system.out.print guru99class1.getName() + " "); } system.out.println(); //Get access modifiers using get Modifiers() method and toString() method of java.lang.reflect.Modifier class int guru99AccessModifier= guru99classObj.getModifiers(); // Print the access modifiers System.Out.println("Access modifiers of the class are : " +Modifier.tostring(guru99AccessModifier)); } }
- druk de naam van de klasse af met behulp van de getName-methode
- Druk de naam van de superklasse af met de methode getSuperClass().getName().
- Druk de naam van de geïmplementeerde interfaces af
- Druk de toegangsmodifiers af die door de klasse worden gebruikt
Voorbeeld 2: Metagegevens van variabelen verkrijgen
De volgende voorbeelden laten zien hoe u metagegevens van een variabele kunt verkrijgen:
Hier maken we een klasse met de naam Guru99VariableMetaData .class met enkele variabelen:
package guru; public class Guru99VariableMetaData { public static int guru99IntVar1=1111; static int guru99IntVar2=2222; static String guru99StringVar1="guru99.com"; static String guru99StringVar2="Learning Reflection API"; }
-
Maak het klasseobject van de bovenstaande klasse, dwz Guru99VariableMetaData.class, zoals hieronder:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
-
Haal de metagegevens op in de vorm van een veldarray met behulp van getFields() or getDeclaredFields() methoden zoals hieronder:
Field[] guru99Field1= guru99ClassObjVar .getFields(); Field[] guru99Fiel2= guru99ClassObjVar .getDeclaredFields();
getFields() method retourneert metagegevens van de publieke variabele uit de opgegeven klasse en uit de superklasse ervan.
getDeclaredFields() methode retourneert alleen metagegevens van alle variabelen uit de opgegeven klasse.
- Haal de naam van de variabelen op met de methode “public String getName()”.
- Haal het datatype van de variabelen op met behulp van de “public Class getType()”-methode.
-
Haal de waarde van de variabele op met behulp van de “public xxx get (Field)” -methode.
Hier kan xxx een byte of een afkorting zijn van elk type waarde dat we willen ophalen.
-
Haal de toegangsmodifiers van de variabelen op met behulp van de methoden getModifier() en Modifier.toString(int i).
Hier schrijven we een klasse om de metagegevens op te halen van de variabelen die aanwezig zijn in de klasse Guru99VariableMetaData .class:
package guru; import java.lang.reflect.Field; public class Guru99VariableMetaDataTest { public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException { // Create Class object for Guru99VariableMetaData.class Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass(); // Get the metadata of all the fields of the class Guru99VariableMetaData Field[] guru99Field1= guru99ClassObjVar.getDeclaredFields(); // Print name, datatypes, access modifiers and values of the varibales of the specified class for(Field field : guru99Field1) { System.out.println("Variable name : "+field.getName()); System.out.println("Datatypes of the variable :"+field.getType()); int guru99AccessModifiers = field.getModifiers(); System.out.printlln("Access Modifiers of the variable : "+Modifier.toString(guru99AccessModifiers)); System.out.println("Value of the variable : "+field.get(guru99ClassVar)); System.out.println(); system.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ; } } }
- Klassenobject gemaakt voor Guru99VariableMetaData.class
- Ik heb alle metagegevens van de variabelen in een veldarray
- Alle namen van variabelen in de klasse Guru99VariableMetaData.class afgedrukt
- Alle gegevenstypen van de variabelen in de klasse Guru99VariableMetaData.class afgedrukt
- Alle toegangsmodificatoren van de variabelen in de klasse Guru99VariableMetaData.class afgedrukt
- Waarden van alle variabelen afgedrukt in Alle gegevenstypen van de variabelen in de klasse Guru99VariableMetaData.class afgedrukt
-
Maak het klasseobject van de bovenstaande klasse, dwz Guru99MethodMetaData.class, zoals hieronder:
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData (); Class guru99ClassObjVar = guru99ClassVar.getClass();
-
Haal methode-informatie op in een Method-array met behulp van de methoden getMethods() en getDeclaredMethods(), zoals hieronder:
Method[] guru99 Method 1= guru99ClassObjVar .get Methods(); Method [] guru99 Method 2= guru99ClassObjVar .getDeclared Method s();
getMethods() method retourneert metagegevens van de openbare methoden van de opgegeven klasse en van de superklasse ervan.
getDeclaredMethods() method retourneert alleen metagegevens van alle methoden uit de opgegeven klasse.
- Haal de naam op van de methode die gebruikt wordt getName () methode.
- Haal het retourtype van de methode op met behulp van getReturnType() methode.
- Krijg toegangsmodificatoren van de methoden die gebruiken getModifiers() en Modifiers.toString(int i) werkwijzen.
- Methodeparametertypen ophalen met behulp van getParameterTypes() methode die een klassenarray retourneert.
-
Krijg een gegenereerde uitzondering met behulp van getExceptionTypes() methode die een klassenarray retourneert.
- Klassenobject gemaakt voor Guru99MethodMetaData.class
- Ik heb alle metagegevens van alle methoden in een Method-array
- Alle methodenamen afgedrukt die aanwezig zijn in de klasse Guru99MethodMetaData.class
- Afgedrukte retourtypen van de methoden in de klasse Guru99MethodMetaData.class
- Alle toegangsmodificatoren van de methoden in de klasse Guru99MethodMetaData.class afgedrukt
- Afgedrukte parametertypen van de methoden in Guru99MethodMetaData.class
-
Afgedrukte uitzonderingen worden gegenereerd door methoden in Guru99MethodMetaData.class
- Klassenobject gemaakt voor Guru99Constructor.class
- Ik heb alle metadata van alle constructors in een Constructor-array
- Alle namen van de constructor afgedrukt die aanwezig zijn in de klasse Guru99Constructor.class
- Alle toegangsmodificatoren van de constructors in de klasse Guru99Constructor.class afgedrukt
- Afgedrukte parametertypen van de constructors in Guru99Constructor.class
- Gedrukte uitzonderingen worden gegenereerd door constructors in Guru99Constructor.class
- Reflectieprogrammering in Java helpt bij het ophalen en wijzigen van informatie over klassen en klasseleden, zoals variabelen, methoden en constructors.
- Reflectie-API in Java kan worden geïmplementeerd met behulp van klassen in het java.lang.reflect-pakket en methoden van de java.lang.Class-klasse.
- Enkele veelgebruikte methoden van de klasse java.lang.Class zijn getName (), getSuperclass (), getInterfaces (), getModifiers () enz.
- Enkele veelgebruikte klassen in het pakket java.lang.reflect zijn Field, Method, Constructor, Modifier, enz.
- Reflection API heeft toegang tot privémethoden en variabelen van een klasse die een beveiligingsrisico kunnen vormen.
- Reflection API is een krachtige mogelijkheid die wordt geboden door Java, maar het brengt wel wat overhead met zich mee, zoals tragere prestaties, beveiligingsproblemen en toestemmingsproblemen. Daarom moet de reflectie-API worden beschouwd als het laatste redmiddel om een bewerking uit te voeren.
Voorbeeld 3: Metagegevens van de methode verkrijgen
De volgende voorbeelden laten zien hoe u metagegevens van een methode kunt verkrijgen:
Hier maken we een klasse met de naam Guru99MethodMetaData .class met enkele methoden
package guru; import java.sql.SQLException; public class Guru99MethodMetaData { public void guru99Add(int firstElement, int secondElement , String result) throws ClassNotFoundException, ClassCastException{ System.out.println("Demo method for Reflextion API"); } public String guru99Search(String searchString) throws ArithmeticException, InterruptedException{ System.out.println("Demo method for Reflection API"); return null; } public void guru99Delete(String deleteString) throws SQLException{ System.out.println("Demo method for Reflection API"); } }
Stappen om de metadata over de methoden in de bovenstaande klasse te verkrijgen:
Hier schrijven we een klasse om de metagegevens op te halen van de methoden die aanwezig zijn in de klasse Guru99MethodMetaData.class:
package guru; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class Guru99MethodMetaDataTest { public static void main (String[] args) { // Create Class object for Guru99Method MetaData.class class guru99ClassObj = Guru99MethodMetaData.class; // Get the metadata or information of all the methods of the class using getDeclaredMethods() Method[] guru99Methods=guru99classObj.getDeclaredMethods(); for(Method method : guru99Methods) { // Print the method names System.out.println("Name of the method : "+method.getName()); // Print return type of the methods System.out.println("Return type of the method : "+method.getReturnType()); //Get the access modifier list and print int guru99ModifierList = method.getModifiers(); System.Out.printlin ("Method access modifiers : "+Modifier.toString(guru99ModifierList)); // Get and print parameters of the methods Class[] guru99ParamList= method.getParameterTypes(); system.out.print ("Method parameter types : "); for (Class class1 : guru99ParamList){ System.out.println(class1.getName()+" "); } System.out.println(); // Get and print exception thrown by the method Class[] guru99ExceptionList = method. getExceptionTypes(); system.out.print("Excpetion thrown by method :"); for (Class class1 : guru99ExceptionList) { System.out.println (class1.getName() +" "): } System.Out.println(); system.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "); } } }
Voorbeeld 4: Metagegevens van constructeurs verkrijgen
De volgende voorbeelden laten zien hoe u metagegevens van constructoren kunt verkrijgen:
Hier maken we een klasse met de naam Guru99Constructor.class met verschillende constructors:
package guru; import java.rmi.RemoteException; import java.sql.SQLException; public class Guru99Constructor { public Guru99Constructor(int no) throws ClassCastException ,ArithmeticException{ } public Guru99Constructor(int no, String name) throws RemoteException ,SQLException{ } public Guru99Constructor(int no, String name, String address) throws InterruptedException{ } }
Hier schrijven we een klasse om de metagegevens op te halen van de constructors die aanwezig zijn in de klasse Guru99Constructor.class:
package guru; import java.lang.reflect.Constructor; public class Guru99ConstructorMetaDataTest { public static void main (String[] args) { // Create Class object for Guru99Constructor.class Class guru99Class=Guru99Constructor.class; // Get all the constructor information in the Constructor array Constructor[] guru99ConstructorList = guru99Class.getConstructors(); for (Constructor constructor : guru99ConstructorList) { // Print all name of each constructor System.out.println("Constrcutor name : "+constructor.getName()); //Get and print access modifiers of each constructor int guru99Modifiers= constructor.getModifiers(); System.Out.printlin ("Constrctor modifier : "+Modifier.toString(guru99Modifiers)); // Get and print parameter types Class[] guru99ParamList=constructor.getParameterTypes(); System.out.print ("Constrctor parameter types :"); for (Class class1 : guru99ParamList) { System.out.println(class1.getName() +" "); } System. out.println(); // Get and print exception thrown by constructors Class[] guru99ExceptionList=constructor.getFxceptionTypes(); System.out.println("Exception thrown by constructors :"); for (Class class1 : guru99ExceptionList) { System.out.println(class1.getName() +" "); } System.out.println(); System.out.println("*******************************************"); } } }