Java Урок за API на Reflection с пример

В какво е отражение Java?

Java Отражението е процес на анализиране и модифициране на всички възможности на клас по време на изпълнение. API за отражение в Java се използва за манипулиране на клас и неговите членове, които включват полета, методи, конструктор и т.н. по време на изпълнение.

Едно предимство на API за отражение в Java е, че може да манипулира и частни членове на класа.

Пакетът java.lang.reflect предоставя много класове за прилагане на отражение java. Методите на класа java.lang.Class се използват за събиране на пълните метаданни на определен клас.

Клас в пакета java.lang.reflect

Следва списък на различни Java класове в java.lang.package за реализиране на отражение-

  • Област: Този клас се използва за събиране на декларативна информация като тип данни, модификатор за достъп, име и стойност на променлива.
  • Начин на доставка: Този клас се използва за събиране на декларативна информация като модификатор за достъп, тип връщане, име, типове параметри и тип изключение на метод.
  • конструктор: Този клас се използва за събиране на декларативна информация като модификатор за достъп, име и типове параметри на конструктор.
  • Промени: Този клас се използва за събиране на информация за определен модификатор на достъп.

Методи, използвани в java.lang.Class

  • Обществен низ getName (): Връща името на класа.
  • публичен клас getSuperclass(): Връща справката за супер клас
  • Публичен клас[] getInterfaces() : Връща масив от интерфейси, реализирани от посочения клас
  • Обществено в getModifiers (): Връща целочислена стойност, представляваща модификаторите на посочения клас, която трябва да бъде предадена като параметър на „публичен статичен низ към Низ (int 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;
		}
	}
  • Следващият пример показва различни начини за създаване на обект от клас “class”:
  • Пример 1: Как да получите метаданни на клас

    Следващият пример показва как да получите метаданни като: име на клас, име на супер клас, внедрени интерфейси и модификатори за достъп на клас.

    Ще получим метаданните на класа по-долу, наречен Guru99Base.class:

    Вземете метаданни на класа

    import java.io.Serializable;
    public abstract class Guru99Base implements Serializable,Cloneable {
    }
    
    1. Името на класа е: Guru99Base
    2. Неговите модификатори за достъп са: public и abstract
    3. Има внедрени интерфейси: Serializable и Cloneable
    4. Тъй като не е разширил изрично нито един клас, неговият супер клас е: java.lang.Object

    Класът по-долу ще получи метаданните на Guru99Base.class и ще ги отпечата:

    Вземете метаданни на класа

    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. отпечатайте името на класа, като използвате метода getName
    2. Отпечатайте името на суперкласа, като използвате метода getSuperClass().getName().
    3. Отпечатайте името на внедрените интерфейси
    4. Отпечатайте модификаторите за достъп, използвани от класа

    Вземете метаданни на класа

    Вземете метаданни на класа

    Пример 2: Как да получите метаданни на променлива

    Следните примери показват как да получите метаданни на променлива:

    Тук създаваме клас с име Guru99VariableMetaData .class с някои променливи:

    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";    
    }	
    
    Стъпки за получаване на метаданните за променливите в горния клас:
    1. Създайте обекта на класа на горния клас, т.е. Guru99VariableMetaData.class, както е показано по-долу:
        Guru99VariableMetaData  guru99ClassVar  = new Guru99VariableMetaData();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
    2. Вземете метаданните под формата на полеви масив, като използвате getFields() or getDeclaredFields() методи като по-долу:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    getFields() методът връща метаданни на публичната променлива от посочения клас, както и от неговия суперклас.

    getDeclaredFields() методът връща метаданни на всички променливи само от посочения клас.

    1. Вземете името на променливите, като използвате метода „public String getName()“.
    2. Вземете типа данни на променливите, като използвате метода „public Class getType()“.
    3. Вземете стойността на променливата, като използвате метода „public xxx get (Field)“.

      Тук xxx може да бъде байт или кратък от всеки тип стойност, която искаме да извлечем.

    4. Вземете модификаторите за достъп на променливите, като използвате методите getModifier() и Modifier.toString(int i).

      Тук пишем клас, за да получим метаданните на променливите, присъстващи в класа 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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ;
      	}
      	}
      }
      
      1. Създаден клас обект за Guru99VariableMetaData.class
      2. Получих всички метаданни на променливите в полеви масив
      3. Отпечата всички имена на променливи в класа Guru99VariableMetaData.class
      4. Отпечата всички типове данни на променливите в класа Guru99VariableMetaData.class
      5. Отпечата всички модификатори за достъп на променливите в класа Guru99VariableMetaData.class
      6. Отпечатани стойности на всички променливи в Отпечатани всички типове данни на променливите в класа Guru99VariableMetaData.class

      Вземете метаданни на метода

      Вземете метаданни на метода

      Пример 3: Как да получите метаданни на метода

      Следните примери показват как да получите метаданни на метод:

      Тук създаваме клас с име Guru99MethodMetaData .class с някои методи

      Вземете метаданни на метода

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

      Стъпки за получаване на метаданните за методите в горния клас:

      1. Създайте обекта на класа на горния клас, т.е. Guru99MethodMetaData.class, както е показано по-долу:
        Guru99MethodMetaData  guru99ClassVar  = new Guru99MethodMetaData  ();
        Class  guru99ClassObjVar  = guru99ClassVar.getClass();
      2. Вземете информация за метод в масив Method, като използвате метода getMethods() и getDeclaredMethods(), както е показано по-долу:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

        getMethods() метод връща метаданни на публичните методи от посочения клас, както и от неговия супер клас.

        getDeclaredMethods() метод връща метаданни на всички методи само от посочения клас.

      3. Получете името на използвания метод getName () метод.
      4. Вземете връщания тип на използвания метод getReturnType() метод.
      5. Вземете модификатори за достъп на използваните методи getModifiers() намлява Modifiers.toString(int i) методи.
      6. Получете типове параметри на метода с помощта getParameterTypes() метод, който връща масив от клас.
      7. Получаване на изключение чрез getExceptionTypes() метод, който връща масив от клас.

      Тук пишем клас, за да получим метаданните на методите, присъстващи в класа 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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ");
      		
      		}
       
      	}
      }
      
      1. Създаден клас обект за Guru99MethodMetaData.class
      2. Получих всички метаданни на всички методи в масив от методи
      3. Отпечата всички имена на методи, присъстващи в класа Guru99MethodMetaData.class
      4. Отпечатани връщани типове на методите в класа Guru99MethodMetaData.class
      5. Отпечата всички модификатори за достъп на методите в класа Guru99MethodMetaData.class
      6. Отпечатани типове параметри на методите в Guru99MethodMetaData.class
      7. Отпечатаните изключения се хвърлят от методи в Guru99MethodMetaData.class

        Вземете метаданни на метода

      Вземете метаданни на метода

      Пример 4: Как да получите метаданни на конструкторите

      Следните примери показват как да получите метаданни на конструкторите:

      Тук създаваме клас с име Guru99Constructor.class с различни конструктори:

      Вземете метаданни на конструктори

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

      Тук пишем клас, за да получим метаданните на конструкторите, присъстващи в класа 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("*******************************************");
      		}
      	}
      }
      
      1. Създаден клас обект за Guru99Constructor.class
      2. Получих всички метаданни на всички конструктори в масив Constructor
      3. Отпечата всички имена на конструктори, присъстващи в класа Guru99Constructor.class
      4. Отпечата всички модификатори за достъп на конструкторите в класа Guru99Constructor.class
      5. Отпечатани типове параметри на конструкторите в Guru99Constructor.class
      6. Отпечатаните изключения се хвърлят от конструктори в Guru99Constructor.class

      Вземете метаданни на конструктори

      Вземете метаданни на конструктори

      Oбобщение

      • Програмирането на отразяване в java помага при извличане и модифициране на информация за класове и членове на класа като променлива, методи, конструктори.
      • API за отражение в Java може да се реализира с помощта на класове в пакета java.lang.reflect и методите на класа java.lang.Class.
      • Някои често използвани методи на класа java.lang.Class са getName (), getSuperclass (), getInterfaces (), getModifiers () и т.н.
      • Някои често използвани класове в пакета java.lang.reflect са Field, Method, Constructor, Modifier и др.
      • Reflection API може да има достъп до частни методи и променливи на клас, който може да представлява заплаха за сигурността.
      • Reflection API е мощна възможност, предоставена от Java, но идва с някои допълнителни разходи, като по-бавна производителност, уязвимост на сигурността и проблем с разрешението. Следователно API за отражение трябва да се третира като последно средство за извършване на операция.