Java บทช่วยสอน Reflection API พร้อมตัวอย่าง

การสะท้อนกลับอยู่ในอะไร Java?

Java การสะท้อนกลับเป็นกระบวนการของการวิเคราะห์และแก้ไขความสามารถทั้งหมดของคลาสในขณะรันไทม์ Reflection API ใน Java ใช้เพื่อจัดการคลาสและสมาชิกซึ่งรวมถึงฟิลด์ วิธีการ ตัวสร้าง ฯลฯ ขณะรันไทม์

ข้อดีอย่างหนึ่งของ Reflection API ใน Java คือสามารถจัดการสมาชิกส่วนตัวของชั้นเรียนได้เช่นกัน

แพ็คเกจ java.lang.reflect มีหลายคลาสเพื่อใช้การสะท้อน java.Methods ของคลาส java.lang.Class ใช้เพื่อรวบรวมข้อมูลเมตาที่สมบูรณ์ของคลาสใดคลาสหนึ่ง

คลาสในแพ็คเกจ java.lang.reflect

ต่อไปนี้เป็นรายการของ ต่างๆ Java ชั้นเรียน ใน java.lang.package เพื่อใช้การสะท้อนกลับ

  • สนาม: คลาสนี้ใช้เพื่อรวบรวมข้อมูลการประกาศ เช่น ประเภทข้อมูล ตัวแก้ไขการเข้าถึง ชื่อ และค่าของตัวแปร
  • วิธี: คลาสนี้ใช้เพื่อรวบรวมข้อมูลการประกาศ เช่น ตัวดัดแปลงการเข้าถึง ประเภทการส่งคืน ชื่อ ประเภทพารามิเตอร์ และประเภทข้อยกเว้นของวิธีการ
  • นวกรรมิก: คลาสนี้ใช้เพื่อรวบรวมข้อมูลการประกาศ เช่น ตัวแก้ไขการเข้าถึง ชื่อ และประเภทพารามิเตอร์ของตัวสร้าง
  • เปลี่ยนแปลง: คลาสนี้ใช้เพื่อรวบรวมข้อมูลเกี่ยวกับตัวแก้ไขการเข้าถึงเฉพาะ

วิธีการที่ใช้ใน java.lang.Class

  • สตริงสาธารณะ getName (): ส่งกลับชื่อของชั้นเรียน
  • คลาสสาธารณะ getSuperclass(): ส่งคืนการอ้างอิงคลาสระดับสูง
  • ระดับสาธารณะ [] getInterfaces () : ส่งคืนอาร์เรย์ของอินเทอร์เฟซที่ใช้งานโดยคลาสที่ระบุ
  • สาธารณะใน getModifiers (): ส่งกลับค่าจำนวนเต็มที่แสดงถึงตัวดัดแปลงของคลาสที่ระบุซึ่งจำเป็นต้องส่งเป็นพารามิเตอร์ไปที่ “สาธารณะสตริงคงที่ 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;
		}
	}
  • ตัวอย่างต่อไปนี้แสดงให้เห็นวิธีต่างๆ ในการสร้างอ็อบเจ็กต์ของคลาส "คลาส":
  • ตัวอย่างที่ 1: วิธีรับข้อมูลเมตาของคลาส

    ตัวอย่างต่อไปนี้จะแสดงวิธีรับข้อมูลเมตา เช่น ชื่อคลาส ชื่อซูเปอร์คลาส อินเทอร์เฟซที่นำไปใช้งาน และตัวปรับแต่งการเข้าถึงของคลาส

    เราจะได้รับข้อมูลเมตาของคลาสด้านล่างชื่อ Guru99Base.class:

    รับข้อมูลเมตาของคลาส

    import java.io.Serializable;
    public abstract class Guru99Base implements Serializable,Cloneable {
    }
    
    1. ชื่อของคลาสคือ: Guru99Base
    2. ตัวแก้ไขการเข้าถึงคือ: สาธารณะและนามธรรม
    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 : วิธีรับ Metadata ของตัวแปร

    ตัวอย่างต่อไปนี้แสดงให้เห็นวิธีการรับข้อมูลเมตาของตัวแปร:

    ที่นี่ เรากำลังสร้างคลาสชื่อ 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. รับข้อมูลเมตาในรูปแบบของอาร์เรย์ฟิลด์โดยใช้ รับฟิลด์() or getDeclaredFields () วิธีการดังต่อไปนี้:
      Field[]  guru99Field1= guru99ClassObjVar .getFields();
      Field[]  guru99Fiel2= guru99ClassObjVar .getDeclaredFields();

    รับฟิลด์() วิธีการส่งคืนข้อมูลเมตาของตัวแปรสาธารณะจากคลาสที่ระบุเช่นเดียวกับจากคลาสซุปเปอร์

    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 : วิธีรับ Metadata ของ Method

      ตัวอย่างต่อไปนี้แสดงให้เห็นวิธีการรับข้อมูลเมตาของวิธีการ:

      ที่นี่ เรากำลังสร้างคลาสชื่อ 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. รับข้อมูลเมธอดในอาร์เรย์เมธอดโดยใช้เมธอด getMethods() และ getDeclaredMethods() ดังต่อไปนี้:
        Method[]  guru99 Method 1= guru99ClassObjVar .get Methods();
        Method []  guru99 Method 2= guru99ClassObjVar .getDeclared Method s();

        รับวิธีการ() method ส่งคืนข้อมูลเมตาของวิธีการสาธารณะจากคลาสที่ระบุและจากคลาสซุปเปอร์

        getDeclaredMethods () method ส่งคืนข้อมูลเมตาของวิธีการทั้งหมดจากคลาสที่ระบุเท่านั้น

      3. รับชื่อของวิธีการที่ใช้ getName () วิธี
      4. รับประเภทการส่งคืนของวิธีการที่ใช้ getReturnType() วิธี
      5. รับตัวแก้ไขการเข้าถึงของวิธีการที่ใช้ รับโมดิฟายเออร์() รวมถึง ตัวดัดแปลง.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{  }							
      }

      ที่นี่ เรากำลังเขียนคลาสเพื่อรับข้อมูลเมตาของ Constructor ที่มีอยู่ในคลาส 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. รับข้อมูลเมตาทั้งหมดของตัวสร้างทั้งหมดในอาร์เรย์ตัวสร้าง
      3. พิมพ์ชื่อของตัวสร้างทั้งหมดที่มีอยู่ในคลาส Guru99Constructor.class
      4. พิมพ์ตัวดัดแปลงการเข้าถึงทั้งหมดของ Constructor ในคลาส Guru99Constructor.class
      5. ประเภทพารามิเตอร์ที่พิมพ์ของ Constructor ใน Guru99Constructor.class
      6. ข้อยกเว้นที่พิมพ์ออกมาจะถูกส่งโดยตัวสร้างใน Guru99Constructor.class

      รับข้อมูลเมตาของตัวสร้าง

      รับข้อมูลเมตาของตัวสร้าง

      สรุป

      • การเขียนโปรแกรม Reflection ใน Java ช่วยในการดึงและแก้ไขข้อมูลเกี่ยวกับคลาสและสมาชิกคลาส เช่น ตัวแปร วิธีการ ตัวสร้าง
      • Reflection 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 ของรีเฟลกชันจึงควรได้รับการพิจารณาเป็นทางเลือกสุดท้ายในการดำเนินการ