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. ชื่อของชั้นเรียนคือ: Guru99ฐาน
    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 : วิธีรับ 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{  }							
      }

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

    สรุปโพสต์นี้ด้วย: