เฟรมเวิร์กกระแสหลักจำนวนมากใช้เทคโนโลยีการสะท้อน ตัวอย่างเช่น เฟรมเวิร์ก ssh ใช้เทคโนโลยีสองอย่าง: xml เป็นไฟล์การกำหนดค่า + เทคโนโลยีการสะท้อน
แพ็คเกจคลาสที่เกี่ยวข้องกับการสะท้อนกลับ
java.lang.reflect.*; และ java.lang.Class;
ทุกประเภทใน Java (รวมถึงประเภทพื้นฐาน) สอดคล้องกับอ็อบเจ็กต์ Class และคลาสนี้คือ java.lang.Class นั่นคือแต่ละประเภทมีวัตถุคลาสที่สอดคล้องกันในคลาสไม่มีตัวสร้างสาธารณะ โปรดทราบว่าไม่ใช่ว่าไม่มีการเข้าถึงแบบสาธารณะ
วิธีรับวัตถุคลาส
คัดลอกรหัสรหัส ดังต่อไปนี้:
.สำหรับแต่ละ object.getCalss() คุณจะได้รับคลาสที่เกี่ยวข้อง
.Class.forName(String) วิธีการเขียนของ String: package name.class name อ็อบเจ็กต์ที่สอดคล้องกับชื่อแพ็คเกจ ชื่อคลาส จะถูกสร้างขึ้น หมายเหตุ: 1.2 ใช้กับประเภทการอ้างอิงเท่านั้น
. สำหรับประเภทพื้นฐาน: คลาสการห่อหุ้ม TYPE แสดงถึงคลาสอ็อบเจ็กต์ของประเภทพื้นฐานที่สอดคล้องกัน
.ประเภท, คลาส. <ประเภท 4 เป็นสากล>
จากสี่วิธีข้างต้น มีเพียงวิธีที่ 2 เท่านั้นที่เป็นไดนามิก เพียงเปลี่ยนแพ็คเกจก็มีศักยภาพแบบไดนามิก ดังนั้น หากคุณต้องการรวบรวมการเขียนโปรแกรมแบบไดนามิกอย่างแท้จริง คุณสามารถใช้วิธีที่ 2 เท่านั้น
แต่ละประเภทมีออบเจ็กต์คลาสเพียงรายการเดียว นั่นคือ มีที่อยู่เดียวเท่านั้น แต่ประเภทที่แตกต่างกันจะแตกต่างกัน
ดังนั้นผลลัพธ์การพิมพ์ต่อไปนี้จึงเป็นจริงทั้งหมด
คัดลอกรหัสรหัส ดังต่อไปนี้:
//คู่และประเภทอ้างอิง
คลาส c1 = "".getClass();
คลาส c2 = Class.forName("java.lang.String");
คลาส c3 = String.class;
System.out.println(c1 ==c2);//true
//สำหรับประเภทพื้นฐาน
คลาส num1 = จำนวนเต็ม TYPE;
คลาส num2 = int.class;
System.out.println(num1 == num2);//true
การสะท้อนกลับเพื่อให้ได้วิธีการที่เกี่ยวข้องกันของสมาชิกในชั้นเรียน
[รับโครงสร้าง <ตามประเภทพารามิเตอร์>] (โดยทั่วไปใช้โดยไม่มีการประกาศ)
คัดลอกรหัสรหัส ดังต่อไปนี้:
ตัวสร้าง <T> getConstructor (คลาส <?>... ประเภทพารามิเตอร์)
ส่งคืนวัตถุตัวสร้างที่สะท้อนถึงตัวสร้างสาธารณะที่ระบุของคลาสที่แสดงโดยวัตถุคลาสนี้
ตัวสร้าง<?>[] getConstructors()
ส่งคืนอาร์เรย์ที่มีวัตถุตัวสร้างที่สะท้อนถึงตัวสร้างสาธารณะทั้งหมดของคลาสที่แสดงโดยวัตถุคลาสนี้
ตัวสร้าง <T> getDeclaredConstructor (คลาส <?>... ประเภทพารามิเตอร์)
ส่งคืนวัตถุ Constructor ที่สะท้อนถึงวิธีการ Constructor ที่ระบุสำหรับคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุ Class นี้
ตัวสร้าง<?>[] getDeclaredConstructors()
ส่งกลับอาร์เรย์ของวัตถุ Constructor ที่สะท้อนถึงวิธีการสร้างทั้งหมดที่ประกาศโดยคลาสที่แสดงโดยวัตถุคลาสนี้
[รับแอตทริบิวต์ <ตามชื่อแอตทริบิวต์>] (มักใช้กับประกาศ เนื่องจากแอตทริบิวต์โดยทั่วไปเป็นแบบส่วนตัว)
คัดลอกรหัสรหัส ดังต่อไปนี้:
ฟิลด์ getField (ชื่อสตริง)
ส่งคืนวัตถุฟิลด์ที่สะท้อนถึงฟิลด์สมาชิกสาธารณะที่ระบุของคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุคลาสนี้
สนาม[]getFields()
ส่งคืนอาร์เรย์ที่มีวัตถุฟิลด์ซึ่งสะท้อนถึงฟิลด์สาธารณะที่สามารถเข้าถึงได้ทั้งหมดของคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุคลาสนี้
ฟิลด์ getDeclaredField (ชื่อสตริง)
ส่งคืนวัตถุ Field ที่สะท้อนถึงฟิลด์ประกาศที่ระบุของคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุคลาสนี้
ฟิลด์[] getDeclaredFields()
ส่งคืนอาร์เรย์ของออบเจ็กต์ Field ที่สะท้อนถึงฟิลด์ทั้งหมดที่ประกาศโดยคลาสหรืออินเทอร์เฟซที่แสดงโดยออบเจ็กต์คลาสนี้
[รับวิธีการ <ชื่อวิธีการบวกประเภทพารามิเตอร์>] (มักใช้โดยไม่ต้องประกาศ)
คัดลอกรหัสรหัส ดังต่อไปนี้:
วิธีการ getMethod (ชื่อสตริง คลาส<?>... parameterTypes)
ส่งกลับวัตถุวิธีการที่สะท้อนถึงวิธีการสมาชิกสาธารณะที่ระบุของคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุคลาสนี้
วิธีการ[]getMethods()
ส่งคืนอาร์เรย์ที่มีอ็อบเจ็กต์ Method ที่สะท้อนถึงสมาชิกสาธารณะของคลาสหรืออินเทอร์เฟซที่แสดงโดยอ็อบเจ็กต์คลาสนี้ (รวมถึงที่ประกาศโดยคลาสหรืออินเทอร์เฟซนั้น และที่สืบทอดมาจากซูเปอร์คลาสและซูเปอร์อินเทอร์เฟซ)
เมธอด getDeclaredMethod (ชื่อสตริง คลาส<?>... parameterTypes)
ส่งคืนวัตถุวิธีการที่สะท้อนถึงวิธีการประกาศที่ระบุของคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุคลาสนี้
วิธีการ [] getDeclaredMethods ()
ส่งกลับอาร์เรย์ของวัตถุ Method ที่สะท้อนถึงวิธีการทั้งหมดที่ประกาศโดยคลาสหรืออินเทอร์เฟซที่แสดงโดยวัตถุ Class นี้ รวมถึงการเข้าถึงสาธารณะ ป้องกัน ค่าเริ่มต้น (แพ็คเกจ) และวิธีการส่วนตัว แต่ไม่รวมวิธีการที่สืบทอดมา
T อินสแตนซ์ใหม่()
สร้างอินสแตนซ์ใหม่ของคลาสที่แสดงโดยออบเจ็กต์คลาสนี้ <อินสแตนซ์ใหม่() สามารถสร้างวัตถุแบบไดนามิก>
สตริง toString()
แปลงวัตถุเป็นสตริง
สังเกต: newInstance() เรียกใช้คอนสตรัคเตอร์แบบไม่มีพารามิเตอร์ หากคลาสไม่มีคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์ newInstance() จะสร้างข้อยกเว้น
วิธีการประกาศสนับสนุนความเป็นส่วนตัว แต่ไม่สนับสนุนการสืบทอด วิธีการที่ไม่ได้ประกาศสนับสนุนการสืบทอด แต่ไม่สนับสนุนความเป็นส่วนตัว และสามารถทำได้เฉพาะสิ่งที่สาธารณะเท่านั้น
ดังนั้น คุณสมบัติโดยทั่วไปจึงถูกประกาศด้วยการประกาศ เนื่องจากคุณสมบัติโดยทั่วไปนั้นเป็นแบบส่วนตัว โดยทั่วไปวิธีการจะได้รับโดยไม่ต้องมีการประกาศ และโดยทั่วไปแล้วตัวสร้างจะได้รับโดยไม่มีการประกาศ
การสะท้อนการจำลองอินสแตนซ์ได้รับคุณสมบัติและวิธีการที่เกี่ยวข้องในชั้นเรียน
การใช้การสะท้อนเพื่อกำหนดค่าให้กับคุณสมบัติ
วิธีการในภาคสนาม
รับวัตถุ (วัตถุวัตถุ)
ส่งกลับค่าของฟิลด์ที่แสดงโดยฟิลด์นี้บนวัตถุที่ระบุ
ฟิลด์ f = c.getXXField(ชื่อคุณสมบัติ);
ค่า = f.get (วัตถุ);
ชุดโมฆะ (Object obj, ค่า Object)
ตั้งค่าฟิลด์ที่แสดงโดยออบเจ็กต์ Field นี้บนตัวแปรออบเจ็กต์ที่ระบุให้เป็นค่าใหม่ที่ระบุ
f.set(วัตถุ, ค่า);
คลาส<?> getType()
ส่งคืนวัตถุคลาสที่ระบุประเภทที่ประกาศของฟิลด์ที่แสดงโดยวัตถุฟิลด์นี้
ใช้เพื่อรับประเภทของแอตทริบิวต์ (ส่งคืนวัตถุคลาส)
คัดลอกรหัสรหัส ดังต่อไปนี้:
คลาส c = Student.class;
Object obj = c.newInstance(); //สร้างอ็อบเจ็กต์ของคลาส Student
ฟิลด์ f = c.getDeclaredField("name"); // รับแอตทริบิวต์ชื่อ
f.setAccessible(true); //ตั้งค่าการเข้าถึงแบบส่วนตัว
f.set(obj, "จางซาน");
System.out.println(f.get(obj)); //รับค่าของแอตทริบิวต์ชื่อ obj
การใช้การสะท้อนเพื่อเรียกโครงสร้าง การเรียกตัวสร้างจริงคือเมื่อมีการเรียกเมธอด newInstance()
คัดลอกรหัสรหัส ดังต่อไปนี้:
คลาส c = Class.forName("com.clazz.reflect.Student");
Constructor con = c.getConstructor(); // ไม่มีการก่อสร้าง
วัตถุ cObj = c.getConstructor().newInstance();//เรียกตัวสร้างแบบไม่มีพารามิเตอร์
ตัวสร้าง conAll = c.getConstructor (int.class,String.class,int.class);
วัตถุ caobj = conAll.newInstance(1001,"zjamgs",234235);//เรียกตัวสร้างด้วยพารามิเตอร์
System.out.println (caobj); // พิมพ์เอาต์พุต
วิธีการเรียกโดยใช้การสะท้อน Object.Method ชื่อ (ค่า 1,2,3);
เมธอด m = c.getMethoed (ชื่อเมธอด, ประเภทพารามิเตอร์...);
m.inurge (พารามิเตอร์การเรียกอ็อบเจ็กต์) หากพารามิเตอร์ทางการที่ต้องการโดยเมธอดพื้นฐานคือ 0 ความยาวของอาร์เรย์ args ที่ระบุอาจเป็น 0 หรือ null
คัดลอกรหัสรหัส ดังต่อไปนี้:
คลาส c = Class.forName("com.clazz.reflect.Student");
Object obj = c.newInstance(); //สร้างวัตถุ Sutdent
Method msetName = c.getMethod("setName", String.class);//obj ไม่จำเป็นต้องแปลงประเภท
msetName.invoid(obj, "zhangsan");//เรียกเมธอด setName และพารามิเตอร์การส่งผ่าน
วิธีการ msetId = c.getMethod("setId", int.class);
msetId.วิงวอน(obj, 409090202);
System.out.println(obj);
ตัวอย่างการใช้งานสะท้อนแสง คลาสเอนทิตี
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ org.dennisit.reflect.entity;
นำเข้า java.io.Serializable;
-
-
*ผู้ใช้.java
-
* @เวอร์ชั่น: 1.1.1.1
-
* @author: Su Ruonian<a href="mailto:
[email protected]">ส่งอีเมล</a>
-
* @since: 1.0 เวลาสร้าง: 26-2-2556 13:43:56 น.
-
* สิ่งที่ต้องทำ: คลาส User.java ใช้สำหรับ ...
-
-
ผู้ใช้คลาสสาธารณะใช้งาน Serializable {
การทดสอบสตริงส่วนตัว
โมฆะสาธารณะดำเนินการ (ชื่อสตริง, อายุ int) {
System.out.println("name=" + ชื่อ + ",age=" + อายุ);
-
-
ชั้นเรียนทดสอบการสะท้อนกลับ
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ org.dennisit.reflect.main;
นำเข้า java.lang.reflect.Field;
-
-
* ReflectEx.java
-
* @เวอร์ชั่น: 1.1.1.1
-
* @author: Su Ruonian<a href="mailto:
[email protected]">ส่งอีเมล</a>
-
* @since: 1.0 เวลาสร้าง: 26-26-2556 13:46:00 น.
-
* สิ่งที่ต้องทำ: คลาส ReflectEx.java ใช้สำหรับ ...
-
-
ReflectEx คลาสสาธารณะ {
โมฆะคงสาธารณะ main (String [] args) พ่นข้อยกเว้น {
คลาส cls = Class.forName("org.dennisit.reflect.entity.User");
วัตถุ obj = cls.newInstance(); //สร้างวัตถุผู้ใช้
ฟิลด์ f = cls.getDeclaredField("test"); //รับแอตทริบิวต์การทดสอบ
f.setAccessible(true); //เปิดสิทธิ์การเข้าถึงสำหรับการทดสอบคุณสมบัติส่วนตัว
f.set(obj, "zhangsan"); //คัดลอกอีกครั้งเพื่อทดสอบ
System.out.println(f.get(obj)); // รับค่าแอตทริบิวต์การทดสอบของ obj
// รับวิธีการตามชื่อวิธีการดำเนินการ
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.inurge(obj, "dennisit",23); //เรียกวิธีการดำเนินการ
-
-
ผลการดำเนินงาน
คัดลอกรหัสรหัส ดังต่อไปนี้:
จางซาน
ชื่อ=เดนนิส,อายุ=23
ตัวอย่างการเขียนคลาสอินสแตนซ์ไดนามิกแบบสะท้อน
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ org.dennisit.reflect.main;
นำเข้า java.lang.reflect.Field;
นำเข้า java.lang.reflect.Method;
นำเข้า java.util.Map;
นำเข้า java.util.Set;
-
-
* DynamicReflect.java
-
* @เวอร์ชั่น: 1.1.1.1
-
* @author: Su Ruonian<a href="mailto:
[email protected]">ส่งอีเมล</a>
-
* @since: 1.0 เวลาสร้าง: 26-2-2556 13:58:12 น.
-
* สิ่งที่ต้องทำ: ตัวอย่างการสร้างอินสแตนซ์แบบไดนามิกโดยใช้การสะท้อน
-
-
DynamicReflect ระดับสาธารณะ {
วัตถุคงที่สาธารณะ getInstance (String className, Map <String, Object> map) พ่นข้อยกเว้น {
คลาส c = Class.forName (ชื่อคลาส);
วัตถุ obj = c.newInstance(); //วัตถุวัตถุ
Set<String> Keys = map.keySet(); //รับแอตทริบิวต์ที่เกี่ยวข้องทั้งหมด
Field[] fAll = c.getDeclaredFields(); //รับคุณสมบัติทั้งหมดในคลาส
สำหรับ(int i=0;i<fAll.length;i++){
สำหรับ (คีย์สตริง: คีย์) // การจับคู่แบบวนซ้ำ
if(fAll[i].getName().equals(key)){/ //หากแอตทริบิวต์ที่ผู้ใช้ส่งเข้ามาตรงกับชื่อแอตทริบิวต์ในคลาสที่ได้รับ
ฟิลด์ f = c.getDeclaredField(key);//รับแอตทริบิวต์นี้
//สร้างชื่อเมธอด setXxx()
methodName สตริง = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
วิธีการ method = c.getMethod(methodName, f.getType());//รับวิธีการที่เกี่ยวข้องตามชื่อผู้ใช้ที่สร้างขึ้น
method.invoid(obj, map.get(key));//การเรียกเมธอด
}อื่น{
ดำเนินการต่อ;
-
-
-
กลับ obj;
-
-
ต่อไปเราจะทดสอบตัวอย่างการสร้างอินสแตนซ์การสะท้อนแบบไดนามิกที่เราเขียน
คลาสเอนทิตี
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ org.dennisit.reflect.entity;
นำเข้า java.io.Serializable;
-
-
*ผู้ใช้.java
-
* @เวอร์ชัน: 1.1.1
-
* @author: Su Ruonian<a href="mailto:
[email protected]">ส่งอีเมล</a>
-
* @since: 1.0 เวลาสร้าง: 26-2-2556 13:43:56 น.
-
* สิ่งที่ต้องทำ: คลาสเอนทิตี
-
-
ผู้ใช้คลาสสาธารณะใช้งาน Serializable {
ชื่อสตริงส่วนตัว
อายุ int ส่วนตัว
อีเมลสตริงส่วนตัว
ผู้ใช้สาธารณะ () { // ต้องไม่มีตัวสร้างพารามิเตอร์
-
//getter() และ setter()
-
ชั้นเรียนทดสอบหลัก
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ org.dennisit.reflect.main;
นำเข้า java.util.HashMap;
นำเข้า java.util.Map;
นำเข้า org.dennisit.reflect.entity.User;
-
-
* ReflectEx.java
-
* @เวอร์ชัน: 1.1.1
-
* @author: Su Ruonian<a href="mailto:
[email protected]">ส่งอีเมล</a>
-
* @since: 1.0 เวลาสร้าง: 26-26-2556 13:46:00 น.
-
* สิ่งที่ต้องทำ: คลาส ReflectEx.java ใช้สำหรับ ...
-
-
ReflectEx คลาสสาธารณะ {
โมฆะคงสาธารณะ main (String [] args) พ่นข้อยกเว้น {
คลาส cls = Class.forName("org.dennisit.reflect.entity.User");
สตริง className = "org.dennisit.reflect.entity.User";
แผนที่ <String, Object> map = ใหม่ HashMap <String, Object> ();
map.put("ชื่อ", "เดนนิส");
map.put("อายุ", 22);
map.put("อีเมล", "[email protected]");
ผู้ใช้ ผู้ใช้ = (ผู้ใช้)DynamicReflect.getInstance(ชื่อคลาส แผนที่);
System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
-
-
ผลลัพธ์การทำงานของโปรแกรม
คัดลอกรหัสรหัส ดังต่อไปนี้: