Java Посібник Reflection API із прикладом

У чому Рефлексія Java?

Java Рефлексія — це процес аналізу та модифікації всіх можливостей класу під час виконання. Reflection API в Java використовується для маніпулювання класом та його членами, які включають поля, методи, конструктор тощо під час виконання.

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

Пакет java.lang.reflect надає багато класів для реалізації відображення java. Методи класу java.lang.Class використовуються для збору повних метаданих певного класу.

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

Нижче наведено список різний Java класів у java.lang.package для реалізації відображення-

  • Поле: Цей клас використовується для збору декларативної інформації, такої як тип даних, модифікатор доступу, ім’я та значення змінної.
  • Метод: Цей клас використовується для збору декларативної інформації, такої як модифікатор доступу, тип повернення, ім’я, типи параметрів і тип винятку методу.
  • Конструктор: Цей клас використовується для збору декларативної інформації, такої як модифікатор доступу, ім’я та типи параметрів конструктора.
  • Модифікатор: Цей клас використовується для збору інформації про певний модифікатор доступу.

Методи, що використовуються в java.lang.Class

  • Загальнодоступний рядок getName (): повертає назву класу.
  • публічний клас getSuperclass(): повертає посилання на суперклас
  • Public Class[] getInterfaces() : повертає масив інтерфейсів, реалізованих зазначеним класом
  • Загальнодоступний у getModifiers (): Повертає ціле значення, що представляє модифікатори зазначеного класу, яке потрібно передати як параметр до “public static String toString (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. Отримано всі метадані всіх методів у масиві Method
      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

      Отримати метадані конструкторів

      Отримати метадані конструкторів

      Підсумки

      • Програмування відображення в Java допомагає отримувати та змінювати інформацію про класи та члени класу, такі як змінна, методи, конструктори.
      • Reflection API в Java можна реалізувати за допомогою класів у пакеті java.lang.reflect і методів класу java.lang.Class.
      • Деякі часто використовувані методи класу java.lang.Class: getName (), getSuperclass (), getInterfaces (), getModifiers () тощо.
      • Деякі часто використовувані класи в пакеті java.lang.reflect — це поле, метод, конструктор, модифікатор тощо.
      • Reflection API може отримати доступ до приватних методів і змінних класу, які можуть становити загрозу безпеці.
      • Reflection API — це потужна функція, яку надає Java, але це пов’язано з деякими накладними витратами, як-от повільніша продуктивність, вразливість системи безпеки та проблема з дозволом. Отже, API відображення слід розглядати як останній засіб для виконання операції.