Java Reflection API Tutorial med eksempel

Hvad er refleksion i Java?

Java Refleksion er processen med at analysere og รฆndre alle funktionerne i en klasse under kรธrsel. Reflection API i Java bruges til at manipulere klasse og dens medlemmer, som inkluderer felter, metoder, konstruktรธr osv. under kรธrsel.

En fordel ved refleksions API i Java er, det kan ogsรฅ manipulere private medlemmer af klassen.

Java.lang.reflect-pakken giver mange klasser til at implementere refleksions-java. Metoder af java.lang.Class-klassen bruges til at indsamle de komplette metadata for en bestemt klasse.

Klasse i java.lang.reflect-pakken

Fรธlgende er en liste over forskellige Java klasser i java.lang.package for at implementere refleksion-

  • Felt: Denne klasse bruges til at indsamle deklarative oplysninger sรฅsom datatype, adgangsmodifikator, navn og vรฆrdi af en variabel.
  • Metode: Denne klasse bruges til at indsamle deklarative oplysninger sรฅsom adgangsmodifikator, returtype, navn, parametertyper og undtagelsestype for en metode.
  • Constructor: Denne klasse bruges til at indsamle deklarativ information sรฅsom adgangsmodifikator, navn og parametertyper for en konstruktรธr.
  • รฆndring: Denne klasse bruges til at indsamle information om en bestemt adgangsmodifikator.

Metoder brugt i java.lang.Class

  • Offentlig streng getName (): Returnerer navnet pรฅ klassen.
  • offentlig klasse getSuperclass(): Returnerer superklassereferencen
  • Offentlig klasse[] getInterfaces() : Returnerer en rรฆkke grรฆnseflader implementeret af den angivne klasse
  • Offentlig i getModifiers (): Returnerer en heltalsvรฆrdi, der reprรฆsenterer modifikatorerne for den angivne klasse, som skal sendes som en parameter til "offentlig statisk streng til streng (int i )" metode, som returnerer adgangsspecifikationen for den givne klasse.

Sรฅdan fรฅr du fuldstรฆndig information om en klasse

At fรฅ information om variabler, metoder og konstruktรธrer af en klasse, skal vi oprette et objekt af klassen.

Metoder brugt i java.lang.Class

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;
		}
	}
  • Fรธlgende eksempel viser forskellige mรฅder at oprette objekt af klassen "klasse" pรฅ:
  • Eksempel 1: Sรฅdan fรฅr du metadata af klasse

    Fรธlgende eksempel viser, hvordan man fรฅr metadata sรฅsom: Klassenavn, superklassenavn, implementerede grรฆnseflader og adgangsmodifikatorer for en klasse.

    Vi fรฅr metadataene for nedenstรฅende klasse ved navn Guru99Base.class:

    Fรฅ metadata for klasse

    import java.io.Serializable;
    public abstract class Guru99Base implements Serializable,Cloneable {
    }
    
    1. Klassens navn er: Guru99Base
    2. Dets adgangsmodifikatorer er: offentlig og abstrakt
    3. Den har implementeret grรฆnseflader: Serialiserbar og Klonbar
    4. Da den ikke eksplicit har udvidet nogen klasse, er dens superklasse: java.lang.Object

    Nedenstรฅende klasse fรฅr metadataene fra Guru99Base.class og udskriver dem:

    Fรฅ metadata for klasse

    import java.lang.reflect.Modifier;
    public class Guru99GetclassMetaData {
    
    	public static void main (String [] args) throws ClassNotFoundException { 
    	// Create Class object for Guru99Base.class 
    	Class guru99ClassObj = 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));
    	
    	}
    }
    
    1. udskriv navnet pรฅ klassen ved hjรฆlp af getName-metoden
    2. Udskriv navnet pรฅ superklassen ved hjรฆlp af metoden getSuperClass().getName().
    3. Udskriv navnet pรฅ de implementerede grรฆnseflader
    4. Udskriv adgangsmodifikatorerne, der bruges af klassen

    Fรฅ metadata for klasse

    Fรฅ metadata for klasse

    Eksempel 2: Sรฅdan fรฅr du metadata af variabel

    Fรธlgende eksempler viser, hvordan man fรฅr metadata for variable:

    Her opretter vi en klasse ved navn Guru99VariableMetaData .class med nogle variabler:

    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";    
    }	
    
    Trin til at fรฅ metadata om variablerne i ovenstรฅende klasse:
    1. Opret klasseobjektet for ovenstรฅende klasse, dvs. Guru99VariableMetaData.class som nedenfor:
        Guru99VariableMetaData  guru99ClassVar  = new Guru99VariableMetaData();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
    2. Fรฅ metadataene i form af field array vha getFields() or getDeclaredFields() metoder som nedenfor:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    getFields() metode returnerer metadata for den offentlige variabel fra den angivne klasse sรฅvel som fra dens superklasse.

    getDeclaredFields() metoden returnerer kun metadata for alle variablerne fra den angivne klasse.

    1. Hent navnet pรฅ variablerne ved hjรฆlp af metoden "public String getName()".
    2. Hent datatypen for variablerne ved hjรฆlp af metoden "public Class getType()".
    3. Hent vรฆrdien af โ€‹โ€‹variablen ved hjรฆlp af "public xxx get (Field)"-metoden.

      Her kan xxx vรฆre en byte eller kort for enhver type vรฆrdi, vi รธnsker at hente.

    4. Hent adgangsmodifikatorerne til variablerne ved at bruge getModifier() og Modifier.toString(int i) metoderne.

      Her skriver vi en klasse for at fรฅ metadataene for de variable, der er til stede i klassen Guru99VariableMetaData .class:

      Fรฅ metadata af variabel

      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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ;
      	}
      	}
      }
      
      1. Oprettet klasseobjekt til Guru99VariableMetaData.class
      2. Fik alle metadata for variablerne i et feltarray
      3. Udskrev alle variabelnavnene i klassen Guru99VariableMetaData.class
      4. Udskrev alle datatyperne for variablerne i klassen Guru99VariableMetaData.class
      5. Udskrev alle adgangsmodifikatorerne for variablerne i klassen Guru99VariableMetaData.class
      6. Udskrevne vรฆrdier for alle variablerne i Udskrev alle datatyper for variablerne i klassen Guru99VariableMetaData.class

      Fรฅ metadata af metode

      Fรฅ metadata af metode

      Eksempel 3: Sรฅdan fรฅr du metadata af metode

      Fรธlgende eksempler viser, hvordan man fรฅr metadata for en metode:

      Her opretter vi en klasse ved navn Guru99MethodMetaData .class med nogle metoder

      Fรฅ metadata af metode

      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");					
          }	
      }

      Trin til at fรฅ metadata om metoderne i ovenstรฅende klasse:

      1. Opret klasseobjektet for ovenstรฅende klasse, dvs. Guru99MethodMetaData.class som nedenfor:
        Guru99MethodMetaData  guru99ClassVar  = new Guru99MethodMetaData  ();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
      2. Fรฅ metodeoplysninger i et Method-array ved hjรฆlp af getMethods() og getDeclaredMethods()-metoden som nedenfor:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

        getMethods() metode returnerer metadata for de offentlige metoder fra den angivne klasse sรฅvel som fra dens superklasse.

        getDeclaredMethods() metode returnerer kun metadata for alle metoderne fra den angivne klasse.

      3. Fรฅ navnet pรฅ metoden vha getName () fremgangsmรฅde.
      4. Fรฅ metodens returtype vha getReturnType() fremgangsmรฅde.
      5. Fรฅ adgangsmodifikatorer af metoderne ved hjรฆlp af getModifiers() og Modifiers.toString(int i) metoder.
      6. Hent metodeparametertyper vha getParameterTypes() metode, som returnerer et klassearray.
      7. Fรฅ smidt undtagelse ved hjรฆlp af getExceptionTypes() metode, som returnerer et klassearray.

      Her skriver vi en klasse for at fรฅ metadata for metoderne, der findes i klassen Guru99MethodMetaData.class:

      Fรฅ metadata af metode

      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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");
      		
      		}
       
      	}
      }
      
      1. Oprettet klasseobjekt til Guru99MethodMetaData.class
      2. Fik alle metadata for alle metoder i et Method-array
      3. Udskrev alle metodenavne, der findes i klassen Guru99MethodMetaData.class
      4. Udskrevne returtyper af metoderne i klassen Guru99MethodMetaData.class
      5. Udskrev alle adgangsmodifikatorerne for metoderne i klassen Guru99MethodMetaData.class
      6. Udskrevne parametertyper af metoderne i Guru99MethodMetaData.class
      7. Udskrevne undtagelser kastes af metoder i Guru99MethodMetaData.class

        Fรฅ metadata af metode

      Fรฅ metadata af metode

      Eksempel 4: Sรฅdan fรฅr du metadata fra konstruktรธrer

      Fรธlgende eksempler viser, hvordan man fรฅr metadata fra konstruktรธrer:

      Her opretter vi en klasse ved navn Guru99Constructor.class med forskellige konstruktรธrer:

       Fรฅ metadata fra konstruktรธrer

      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{  }							
      }

      Her skriver vi en klasse for at fรฅ metadata fra konstruktรธrerne til stede i klassen Guru99Constructor.class:

      Fรฅ metadata fra konstruktรธrer

      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("*******************************************");
      		}
      	}
      }
      
      1. Oprettet klasseobjekt til Guru99Constructor.class
      2. Fik alle metadata for alle konstruktรธrerne i et Constructor-array
      3. Udskrev alle konstruktรธrens navne i klassen Guru99Constructor.class
      4. Udskrev alle adgangsmodifikatorerne for konstruktรธrerne i klassen Guru99Constructor.class
      5. Udskrevne parametertyper af konstruktรธrerne i Guru99Constructor.class
      6. Udskrevne undtagelser kastes af konstruktรธrer i Guru99Constructor.class

      Fรฅ metadata fra konstruktรธrer

      Fรฅ metadata fra konstruktรธrer

      Resumรฉ

      • Refleksionsprogrammering i java hjรฆlper med at hente og รฆndre information om klasser og klassemedlemmer sรฅsom variable, metoder, konstruktรธrer.
      • Reflection API i Java kan implementeres ved hjรฆlp af klasser i java.lang.reflect-pakken og metoder i java.lang.Class-klassen.
      • Nogle almindeligt anvendte metoder i java.lang.Class-klassen er getName (), getSuperclass (), getInterfaces (), getModifiers () osv.
      • Nogle almindeligt anvendte klasser i java.lang.reflect-pakken er Field, Method, Constructor, Modifier osv.
      • Reflection API kan fรฅ adgang til private metoder og variabler af en klasse, som kan vรฆre en sikkerhedstrussel.
      • Reflection API er en kraftfuld funktion leveret af Java, men det kommer med nogle faste omkostninger sรฅsom langsommere ydeevne, sikkerhedssรฅrbarhed og tilladelsesproblem. Derfor bรธr refleksions-API behandles som den sidste udvej til at udfรธre en operation.

    Opsummer dette indlรฆg med: