การสะท้อนกลับเป็นคุณสมบัติที่สำคัญของภาษา Java เรารู้ว่าก่อนที่จะใช้คลาสเรามักจะสร้างมันขึ้นมาแล้ว เช่น การสร้างไฟล์คลาสแล้วเขียนแอตทริบิวต์ วิธีการ ฯลฯ นั่นคือคลาสประเภทนี้ มันเป็นแบบคงที่ แต่กลไกการสะท้อนช่วยให้คุณสร้างคลาสแบบไดนามิกได้ นอกเหนือจากการสร้างคลาสแบบไดนามิกแล้ว เรายังสามารถรับข้อมูลของอ็อบเจ็กต์ที่คล้ายกันแบบไดนามิกและกำหนดข้อมูลเหล่านี้ให้กับคลาสที่สร้างขึ้นใหม่ ซึ่งค่อนข้างคล้ายกับการโคลนนิ่ง หลายครั้ง เราต้องการคุณสมบัตินี้ในการสร้างคลาสแบบไดนามิก ตัวอย่างเช่น เมื่อประมวลผลธุรกิจบางอย่าง แต่ธุรกิจเหล่านี้แตกต่างกันเล็กน้อย พวกเขามักจะสอดคล้องกับหลายคลาส เมื่อประมวลผล เราต้องใช้การประมวลผลทางธุรกิจที่แตกต่างกันเพื่อเรียกคลาสที่แตกต่างกัน คราวนี้กลไกการสะท้อนกลับมีประโยชน์
ต่อไปนี้เป็นคำอธิบายของแพ็คเกจ java.lang.reflect ใน JDK API:
จัดเตรียมคลาสและอินเทอร์เฟซเพื่อรับข้อมูลการสะท้อนเกี่ยวกับคลาสและอ็อบเจ็กต์ ภายในข้อจำกัดด้านความปลอดภัย การสะท้อนกลับอนุญาตให้โปรแกรมเข้าถึงข้อมูลเกี่ยวกับฟิลด์ วิธีการ และตัวสร้างของคลาสที่โหลด และอนุญาตให้ใช้ฟิลด์ที่สะท้อนกลับ วิธีการ และตัวสร้างเพื่อดำเนินการกับสิ่งที่เทียบเท่าพื้นฐานบนอ็อบเจ็กต์
AccessObject อนุญาตให้ระงับการตรวจสอบการเข้าถึงหาก ReflectPermission ที่จำเป็นพร้อมใช้งาน
อาร์เรย์จัดเตรียมวิธีการคงที่สำหรับการสร้างและการเข้าถึงอาร์เรย์แบบไดนามิก
คลาสในแพ็กเกจนี้ รวมถึง java.lang.Class สามารถปรับให้เข้ากับความต้องการของแอปพลิเคชัน เช่น ดีบักเกอร์ ล่าม ตัวตรวจสอบอ็อบเจ็กต์ เบราว์เซอร์คลาส และบริการ (เช่น Object Serialization และ JavaBeans) ที่จำเป็นต้องเข้าถึงเป้าหมาย วัตถุขึ้นอยู่กับสมาชิกสาธารณะของคลาสรันไทม์) หรือสมาชิกที่ประกาศโดยคลาสที่กำหนด)
ต่อไปนี้ใช้สองตัวอย่างง่ายๆ เพื่อแสดงให้เห็นการใช้การสะท้อน ขั้นแรก ให้สร้างคลาส Person:
คัดลอกรหัสรหัสดังต่อไปนี้:
การทดสอบบรรจุภัณฑ์
บุคคลในชั้นเรียนสาธารณะ {
อายุ int ส่วนตัว
ชื่อสตริงส่วนตัว = "";
สตริงส่วนตัว [] arr = สตริงใหม่ [2];
บุคคลสาธารณะ(){}
บุคคลสาธารณะ (ชื่อสตริง, อายุ int) {
this.name = ชื่อ;
this.age = อายุ;
-
สาธารณะ int getAge() {
อายุกลับ;
-
setAge โมฆะสาธารณะ (อายุ int) {
this.age = อายุ;
-
สตริงสาธารณะ getName() {
ชื่อผู้ส่งคืน;
-
setName โมฆะสาธารณะ (ชื่อสตริง) {
this.name = ชื่อ;
-
สตริงสาธารณะ [] getArr () {
กลับถึง;
-
โมฆะสาธารณะ setArr (สตริง [] arr) {
นี่.arr = arr;
-
-
ตัวอย่างที่ 1: รับข้อมูลแอตทริบิวต์และวิธีการของคลาสบุคคล คัดลอกโค้ดดังต่อไปนี้:
โมฆะคงที่ส่วนตัว testSimpleReflect () {
สตริง className = "test.Person";
พยายาม {
คลาส c = Class.forName (ชื่อคลาส);
ฟิลด์ [] = c.getDeclaredFields();
วิธีการ [] m = c.getDeclaredMethods();
สำหรับ (ฟิลด์ ฟิลด์ : ฟิลด์){
System.out.println(field.getName());
-
สำหรับ (วิธี วิธีการ : m){
System.out.println(m.getClass());
-
} จับ (ClassNotFoundException จ) {
e.printStackTrace();
-
-
มันง่ายมาก คุณสามารถรับคลาสผ่านพาธแพ็คเกจที่คลาสนั้นตั้งอยู่ ในการทำงานจริง มันก็เป็นคลาสที่ใช้บ่อยที่สุดเช่นกัน
ตัวอย่างที่ 2: คัดลอกวัตถุ คัดลอกโค้ด รหัสจะเป็นดังนี้:
@SuppressWarnings("ไม่ได้เลือก")
สำเนาวัตถุคงที่สาธารณะ (วัตถุวัตถุ) พ่นข้อยกเว้น {
// รับประเภทวัตถุ
คลาส classType = object.getClass();
System.out.println("" + classType.getName()); // สร้างอ็อบเจ็กต์ใหม่โดยใช้วิธีการก่อสร้างเริ่มต้น
วัตถุ objectCopy = classType.getConstructor (คลาสใหม่ [] {})
.newInstance(new Object[] {}); // รับคุณสมบัติทั้งหมดของอ็อบเจ็กต์
ฟิลด์ฟิลด์[] = classType.getDeclaredFields();
สำหรับ (int i = 0; i <fields.length; i++) {
ฟิลด์ ฟิลด์ = ฟิลด์[i];
สตริง fieldName = field.getName();
String firstLetter = fieldName.substring(0, 1).toUpperCase(); // รับชื่อของเมธอด getXXX() ที่สอดคล้องกับแอตทริบิวต์
สตริง getMethodName = "get" + firstLetter + fieldName.substring(1); // รับชื่อของเมธอด setXXX() ที่สอดคล้องกับแอตทริบิวต์
สตริง setMethodName = "set" + firstLetter + fieldName.substring(1); // รับเมธอด getXXX() ที่สอดคล้องกับแอตทริบิวต์
วิธีการ getMethod = classType.getMethod(getMethodName,
คลาสใหม่ [] {}); // รับเมธอด setXXX() ที่สอดคล้องกับแอตทริบิวต์
วิธีการ setMethod = classType.getMethod (setMethodName,
new Class[] { field.getType() }); // เรียกเมธอด getXXX() ของออบเจ็กต์ต้นฉบับ
ค่าวัตถุ = getMethod.inrigg (วัตถุ วัตถุใหม่ [] {});
System.out.println(fieldName + /// + value); // เรียกเมธอด setXXX() ของอ็อบเจ็กต์ที่คัดลอก
setMethod.inrigg (objectCopy, วัตถุใหม่ [] { ค่า });
-
กลับ objectCopy;
-
การใช้การสะท้อนเพื่อคัดลอกวัตถุ โดยปกติแล้วเราไม่จำเป็นต้องทำเอง เนื่องจากระบบโอเพ่นซอร์ส BeanUtils ได้ห่อหุ้มสำเนาวัตถุไว้ให้เราแล้ว เราสามารถเรียกวิธีการของมันได้โดยตรง แต่ก็น่าสังเกตว่า BeanUtils นั้นมีพื้นฐานมาจากเช่นกัน บนกลไกการสะท้อนแสงเพื่อทำแพ็คเกจ
นี่คือการโทร:
คัดลอกรหัสรหัสดังต่อไปนี้:
โมฆะคงที่สาธารณะ main (String [] args) {
บุคคล คน = บุคคลใหม่ ("ทอม",22);
สตริง[] strs = สตริงใหม่[]{"a", "b"};
person.setArr(strs);
พยายาม {
บุคคล p = (บุคคล) สำเนา (บุคคล);
System.out.println(p.getName()+">>"+p.getAge());
สำหรับ (String str : p.getArr()){
System.out.println(str);
-
} จับ (ข้อยกเว้นจ) {
e.printStackTrace();
-
// testSimpleReflect();
-