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 )” วิธีการส่งคืนตัวระบุการเข้าถึงสำหรับคลาสที่กำหนด
วิธีรับข้อมูลที่สมบูรณ์เกี่ยวกับชั้นเรียน
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 { }
- ชื่อของคลาสคือ: Guru99Base
- ตัวแก้ไขการเข้าถึงคือ: สาธารณะและนามธรรม
- มีการใช้งานอินเทอร์เฟซ: Serializable และ Cloneable
- เนื่องจากไม่ได้ขยายคลาสใด ๆ อย่างชัดเจน คลาสซุปเปอร์จึงเป็น: 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 Classguru99ClassObj = 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)); } }
- พิมพ์ชื่อของคลาสโดยใช้วิธี getName
- พิมพ์ชื่อของซูเปอร์คลาสโดยใช้เมธอด getSuperClass().getName()
- พิมพ์ชื่อของอินเทอร์เฟซที่นำไปใช้
- พิมพ์ตัวดัดแปลงการเข้าถึงที่ใช้โดยชั้นเรียน
ตัวอย่างที่ 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"; }
-
สร้างคลาสอ็อบเจ็กต์ของคลาสด้านบน เช่น Guru99VariableMetaData.class ดังนี้:
Guru99VariableMetaData guru99ClassVar = new Guru99VariableMetaData(); Class guru99ClassObjVar = guru99ClassVar.getClass();
-
รับข้อมูลเมตาในรูปแบบของอาร์เรย์ฟิลด์โดยใช้ รับฟิลด์() or getDeclaredFields () วิธีการดังต่อไปนี้:
Field[] guru99Field1= guru99ClassObjVar .getFields(); Field[] guru99Fiel2= guru99ClassObjVar .getDeclaredFields();
รับฟิลด์() วิธีการส่งคืนข้อมูลเมตาของตัวแปรสาธารณะจากคลาสที่ระบุเช่นเดียวกับจากคลาสซุปเปอร์
getDeclaredFields () วิธีการส่งคืนข้อมูลเมตาของตัวแปรทั้งหมดจากคลาสที่ระบุเท่านั้น
- รับชื่อของตัวแปรโดยใช้วิธี “public String getName()”
- รับประเภทข้อมูลของตัวแปรโดยใช้วิธี “public Class getType()”
-
รับค่าของตัวแปรโดยใช้วิธี "public xxx get (Field)"
ในที่นี้ xxx อาจเป็นไบต์หรือค่าสั้นๆ ที่เราต้องการดึงข้อมูล
-
รับตัวแก้ไขการเข้าถึงของตัวแปรโดยใช้เมธอด 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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *") ; } } }
- สร้างออบเจ็กต์คลาสสำหรับ Guru99VariableMetaData.class
- รับข้อมูลเมตาทั้งหมดของตัวแปรในอาร์เรย์ฟิลด์
- พิมพ์ชื่อตัวแปรทั้งหมดในคลาส Guru99VariableMetaData.class
- พิมพ์ข้อมูลตัวแปรทั้งหมดในคลาส Guru99VariableMetaData.class
- พิมพ์ตัวแก้ไขการเข้าถึงทั้งหมดของตัวแปรในคลาส Guru99VariableMetaData.class
- พิมพ์ค่าของตัวแปรทั้งหมดใน พิมพ์ประเภทข้อมูลทั้งหมดของตัวแปรในคลาส Guru99VariableMetaData.class
-
สร้างคลาสอ็อบเจ็กต์ของคลาสด้านบน เช่น Guru99MethodMetaData.class ดังนี้
Guru99MethodMetaData guru99ClassVar = new Guru99MethodMetaData (); Class guru99ClassObjVar = guru99ClassVar.getClass();
-
รับข้อมูลเมธอดในอาร์เรย์เมธอดโดยใช้เมธอด getMethods() และ getDeclaredMethods() ดังต่อไปนี้:
Method[] guru99 Method 1= guru99ClassObjVar .get Methods(); Method [] guru99 Method 2= guru99ClassObjVar .getDeclared Method s();
รับวิธีการ() method ส่งคืนข้อมูลเมตาของวิธีการสาธารณะจากคลาสที่ระบุและจากคลาสซุปเปอร์
getDeclaredMethods () method ส่งคืนข้อมูลเมตาของวิธีการทั้งหมดจากคลาสที่ระบุเท่านั้น
- รับชื่อของวิธีการที่ใช้ getName () วิธี
- รับประเภทการส่งคืนของวิธีการที่ใช้ getReturnType() วิธี
- รับตัวแก้ไขการเข้าถึงของวิธีการที่ใช้ รับโมดิฟายเออร์() รวมถึง ตัวดัดแปลง.toString(int i) วิธีการ
- รับประเภทพารามิเตอร์วิธีการโดยใช้ getParameterTypes() วิธีการส่งกลับอาร์เรย์คลาส
-
รับข้อยกเว้นโดยใช้ getExceptionTypes() วิธีการส่งกลับอาร์เรย์คลาส
- สร้างวัตถุคลาสสำหรับ Guru99MethodMetaData.class
- ได้รับข้อมูลเมตาทั้งหมดของวิธีการทั้งหมดในอาร์เรย์วิธีการ
- พิมพ์ชื่อวิธีการทั้งหมดที่มีอยู่ในคลาส Guru99MethodMetaData.class
- พิมพ์ส่งคืนวิธีการในคลาส Guru99MethodMetaData.class
- พิมพ์ตัวดัดแปลงการเข้าถึงทั้งหมดของวิธีการในคลาส Guru99MethodMetaData.class
- ประเภทพารามิเตอร์ที่พิมพ์ของวิธีการใน Guru99MethodMetaData.class
-
ข้อยกเว้นที่พิมพ์ออกมาจะถูกส่งออกไปโดยวิธีการใน Guru99MethodMetaData.class
- สร้างวัตถุคลาสสำหรับ Guru99Constructor.class
- รับข้อมูลเมตาทั้งหมดของตัวสร้างทั้งหมดในอาร์เรย์ตัวสร้าง
- พิมพ์ชื่อของตัวสร้างทั้งหมดที่มีอยู่ในคลาส Guru99Constructor.class
- พิมพ์ตัวดัดแปลงการเข้าถึงทั้งหมดของ Constructor ในคลาส Guru99Constructor.class
- ประเภทพารามิเตอร์ที่พิมพ์ของ Constructor ใน Guru99Constructor.class
- ข้อยกเว้นที่พิมพ์ออกมาจะถูกส่งโดยตัวสร้างใน 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 ของรีเฟลกชันจึงควรได้รับการพิจารณาเป็นทางเลือกสุดท้ายในการดำเนินการ
ตัวอย่างที่ 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"); } }
ขั้นตอนในการรับข้อมูลเมตาเกี่ยวกับวิธีการในคลาสข้างต้น:
ที่นี่ เรากำลังเขียนคลาสเพื่อรับข้อมูลเมตาของวิธีการที่มีอยู่ในคลาส 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("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * "); } } }
ตัวอย่างที่ 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("*******************************************"); } } }