Java Reflection API Tutorial med exempel

Vad är reflektion i Java?

Java Reflektion är processen att analysera och modifiera alla funktioner i en klass vid körning. Reflection API in Java används för att manipulera klass och dess medlemmar som inkluderar fält, metoder, konstruktorer, etc. vid körning.

En fördel med reflektions-API i Java är att det kan manipulera privata medlemmar i klassen också.

Paketet java.lang.reflect tillhandahåller många klasser för att implementera reflektionsjava. Metoder för klassen java.lang.Class används för att samla in fullständig metadata för en viss klass.

Klass i java.lang.reflect-paketet

Följande är en lista över olika Java klasser i java.lang.package för att implementera reflektion-

  • Fält: Denna klass används för att samla in deklarativ information som datatyp, åtkomstmodifierare, namn och värde på en variabel.
  • Metod: Denna klass används för att samla in deklarativ information såsom åtkomstmodifierare, returtyp, namn, parametertyper och undantagstyp för en metod.
  • Konstruktör: Denna klass används för att samla in deklarativ information såsom åtkomstmodifierare, namn och parametertyper för en konstruktor.
  • byta: Denna klass används för att samla information om en viss åtkomstmodifierare.

Metoder som används i java.lang.Class

  • Public String getName (): Returnerar namnet på klassen.
  • public Class getSuperclass(): Returnerar superklassreferensen
  • Public Class[] getInterfaces() : Returnerar en uppsättning gränssnitt implementerade av den angivna klassen
  • Offentlig i getModifiers (): Returnerar ett heltalsvärde som representerar modifierarna för den angivna klassen som måste skickas som en parameter till "public static String toString (int i )" metod som returnerar åtkomstspecifikationen för den givna klassen.

Hur man får fullständig information om en klass

För att få information om variabler, metoder och konstruktörer för en klass, måste vi skapa ett objekt av klassen.

Metoder som används 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öljande exempel visar olika sätt att skapa objekt av klassen "klass":
  • Exempel 1: Hur man får metadata av klass

    Följande exempel visar hur man får metadata som: Klassnamn, superklassnamn, implementerade gränssnitt och åtkomstmodifierare för en klass.

    Vi kommer att få metadata från nedanstående klass som heter Guru99Base.class:

    Få metadata av klass

    import java.io.Serializable;
    public abstract class Guru99Base implements Serializable,Cloneable {
    }
    
    1. Klassens namn är: Guru99Base
    2. Dess åtkomstmodifierare är: offentliga och abstrakta
    3. Den har implementerat gränssnitt: Serialiserbar och Klonbar
    4. Eftersom den inte har utökat någon klass explicit, är dens superklass: java.lang.Object

    Nedan klass kommer att få metadata för Guru99Base.class och skriva ut den:

    Få metadata av klass

    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. skriv ut namnet på klassen med metoden getName
    2. Skriv ut namnet på superklassen med metoden getSuperClass().getName().
    3. Skriv ut namnet på de implementerade gränssnitten
    4. Skriv ut de åtkomstmodifierare som används av klassen

    Få metadata av klass

    Få metadata av klass

    Exempel 2: Hur man får metadata av variabel

    Följande exempel visar hur man får metadata för variabel:

    Här skapar vi en klass som heter Guru99VariableMetaData .class med några 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";    
    }	
    
    Steg för att få metadata om variablerna i ovanstående klass:
    1. Skapa klassobjektet för ovanstående klass, dvs Guru99VariableMetaData.class enligt nedan:
        Guru99VariableMetaData  guru99ClassVar  = new Guru99VariableMetaData();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
    2. Få metadata i form av field array med hjälp av getFields() or getDeclaredFields() metoder enligt nedan:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    getFields() metod returnerar metadata för den publika variabeln från den angivna klassen såväl som från dess superklass.

    getDeclaredFields() metod returnerar endast metadata för alla variabler från den angivna klassen.

    1. Hämta namnet på variablerna med metoden "public String getName()".
    2. Hämta datatypen för variablerna med metoden "public Class getType()".
    3. Få värdet på variabeln med metoden "public xxx get (Field)".

      Här kan xxx vara en byte eller kort av någon typ av värde vi vill hämta.

    4. Hämta åtkomstmodifierarna för variablerna med metoderna getModifier() och Modifier.toString(int i).

      Här skriver vi en klass för att få metadata för variablerna som finns i klassen Guru99VariableMetaData .class:

      Få metadata av 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. Skapat klassobjekt för Guru99VariableMetaData.class
      2. Fick all metadata för variablerna i en Field-array
      3. Skrev ut alla variabelnamn i klassen Guru99VariableMetaData.class
      4. Skriver ut alla datatyper för variablerna i klassen Guru99VariableMetaData.class
      5. Skriver ut alla åtkomstmodifierare för variablerna i klassen Guru99VariableMetaData.class
      6. Utskrivna värden för alla variabler i Utskrivna alla datatyper för variablerna i klassen Guru99VariableMetaData.class

      Få metadata av metod

      Få metadata av metod

      Exempel 3: Hur man skaffar Metadata of Method

      Följande exempel visar hur man får metadata för en metod:

      Här skapar vi en klass som heter Guru99MethodMetaData .class med några metoder

      Få metadata av metod

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

      Steg för att få metadata om metoderna i ovanstående klass:

      1. Skapa klassobjektet för ovanstående klass, dvs Guru99MethodMetaData.class enligt nedan:
        Guru99MethodMetaData  guru99ClassVar  = new Guru99MethodMetaData  ();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
      2. Hämta metodinformation i en metodmatris med metoderna getMethods() och getDeclaredMethods() enligt nedan:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

        getMethods() metod returnerar metadata för de offentliga metoderna från den angivna klassen såväl som från dess superklass.

        getDeclaredMethods() metod returnerar endast metadata för alla metoder från den angivna klassen.

      3. Få namnet på metoden med hjälp av hämta namn () metod.
      4. Hämta returtypen för metoden med hjälp av getReturnType() metod.
      5. Få åtkomstmodifierare av metoderna som använder getModifiers() och Modifiers.toString(int i) metoder.
      6. Hämta metodparametertyper med hjälp av getParameterTypes() metod som returnerar en klassmatris.
      7. Bli kastat undantag med hjälp av getExceptionTypes() metod som returnerar en klassmatris.

      Här skriver vi en klass för att få metadata för metoderna som finns i klassen Guru99MethodMetaData.class:

      Få metadata av metod

      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. Skapat klassobjekt för Guru99MethodMetaData.class
      2. Fick all metadata för alla metoder i en Method array
      3. Skrev ut alla metodnamn som finns i klassen Guru99MethodMetaData.class
      4. Utskrivna returtyper av metoderna i klassen Guru99MethodMetaData.class
      5. Skrivit ut alla åtkomstmodifierare för metoderna i klassen Guru99MethodMetaData.class
      6. Utskrivna parametertyper av metoderna i Guru99MethodMetaData.class
      7. Utskrivna undantag kastas av metoder i Guru99MethodMetaData.class

        Få metadata av metod

      Få metadata av metod

      Exempel 4: Hur man får metadata från konstruktörer

      Följande exempel visar hur man får metadata från konstruktörer:

      Här skapar vi en klass som heter Guru99Constructor.class med olika konstruktörer:

      Få metadata från 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{  }							
      }

      Här skriver vi en klass för att få metadata för konstruktörerna som finns i klassen Guru99Constructor.class:

      Få metadata från 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. Skapat klassobjekt för Guru99Constructor.class
      2. Fick all metadata för alla konstruktörer i en Constructor-array
      3. Skrivet ut alla konstruktörens namn som finns i klassen Guru99Constructor.class
      4. Skrev ut alla åtkomstmodifierare för konstruktörerna i klassen Guru99Constructor.class
      5. Utskrivna parametertyper av konstruktörerna i Guru99Constructor.class
      6. Utskrivna undantag kastas av konstruktörer i Guru99Constructor.class

      Få metadata från konstruktörer

      Få metadata från konstruktörer

      Sammanfattning

      • Reflektionsprogrammering i java hjälper till att hämta och ändra information om klasser och klassmedlemmar såsom variabler, metoder, konstruktorer.
      • Reflection API in Java kan implementeras med hjälp av klasser i paketet java.lang.reflect och metoder för klassen java.lang.Class.
      • Några vanliga metoder för java.lang.Class-klassen är getName (), getSuperclass (), getInterfaces (), getModifiers () etc.
      • Några vanliga klasser i java.lang.reflect-paketet är Field, Method, Constructor, Modifier, etc.
      • Reflection API kan komma åt privata metoder och variabler av en klass som kan vara ett säkerhetshot.
      • Reflection API är en kraftfull funktion som tillhandahålls av Java, men det kommer med vissa omkostnader som långsammare prestanda, säkerhetssårbarhet och behörighetsproblem. Reflektions-API bör därför behandlas som den sista utvägen för att utföra en operation.