กลไกการสะท้อนกลับของ Java อยู่ในสถานะการทำงาน วิธีการวัตถุเรียกว่ากลไกการสะท้อนของภาษา Java แนวคิดของการสะท้อนกลับถูกเสนอครั้งแรกโดยสมิ ธ ในปี 1982 ส่วนใหญ่หมายถึงความสามารถที่โปรแกรมสามารถเข้าถึงตรวจจับและปรับเปลี่ยนสถานะหรือพฤติกรรมของตัวเอง ข้อเสนอของแนวคิดนี้กระตุ้นการวิจัยอย่างรวดเร็วเกี่ยวกับการสะท้อนแสงประยุกต์ในสาขาวิทยาศาสตร์คอมพิวเตอร์ มันถูกนำมาใช้เป็นครั้งแรกในสาขาการออกแบบภาษาการเขียนโปรแกรมและบรรลุความสำเร็จใน LISP และมุ่งเน้นวัตถุ แน่นอนว่าการสะท้อนกลับไม่ใช่แนวคิดใหม่
กลไกการสะท้อน Java ส่วนใหญ่ให้การใช้งานต่อไปนี้:
กำหนดคลาสที่วัตถุใด ๆ เป็นของรันไทม์
สร้างวัตถุของชั้นเรียนใด ๆ ที่รันไทม์
กำหนดตัวแปรสมาชิกและวิธีการของคลาสใด ๆ ที่รันไทม์
วิธีการโทรของวัตถุใด ๆ ที่รันไทม์
ก่อนอื่นมาดูตัวอย่างง่ายๆและใช้ตัวอย่างนี้เพื่อทำความเข้าใจว่ากลไกการสะท้อนของ Java ทำงานอย่างไร
แพ็คเกจ com.wanggc.reflection; นำเข้า java.lang.reflect.method;/*** แบบฝึกหัดการไตร่ตรอง Java * * @author Wanggc * /คลาสสาธารณะ fornametest { /** * ฟังก์ชั่นรายการ * * @param args * พารามิเตอร์ * @throws Exception * ข้อความแสดงข้อผิดพลาด */ โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่นข้อยกเว้น {// รับคลาสคลาส <?> cls = class.fornam e (args [0]); / / รับวัตถุที่เกี่ยวข้องผ่านวิธีการเรียน [] วิธีการ = cls.getMethods ();เมื่อพารามิเตอร์ที่ผ่านคือ java.lang.string ผลลัพธ์ต่อไปนี้จะถูกส่งออก
บูลีนสาธารณะ java.lang.string.equals (java.lang.Object) สาธารณะ java.lang.string java.lang.string.tostring () สาธารณะ int java.lang.string.hashcode () pu blic int java.lang.string.string . เปรียบเทียบ (java.lang.string) สาธารณะ int java.lang.string.Compareto (java.lang.Object) สาธารณะ int java.lang.string.indexof (int) สาธารณะ int java.lang.strin g.indexof (int int) สาธารณะ int java.lang.string.indexof (java.lang.string) สาธารณะ int java.lang.string.indexof (java.lang.string, int) สาธารณะคงที่ Java.lang.string java.lang .String.valueof.valueof (int) สาธารณะคงที่ Java.lang.String java.lang.string.valueof (ถ่าน) สาธารณะคงที่ Java.lang.string java.lang.string java.lang.string.valueof (บูลีน) java.lang.string.valueof (ลอย) สาธารณะคงที่ Java.lang.string java.lang.string.valueof (char [], int, int) สาธารณะคง สาธารณะ tatic java.lang.string java .lang.string.valueof (char []) สาธารณะคงที่ Java.lang.string java.lang.string.valueof (java.lang.Object) Java.lang.String Java lang.string str ing.codepointcount (int, int) สาธารณะ int java.lang.string.comparetoignorecase (java.lang.string) สาธารณะ java.lang.string java.lang.string.concat (java.lang.string .STRING .CONTAINS (java.lang.Charesequence) บูลีนสาธารณะ java.lang.String.Contentequals (java.lang.char.charexence) บูลีนสาธารณะ Java.lang.string.ContEstEquals (java.lang.stringbuffer) สตริง java.lang.string.copyvalueof (char []) สาธารณะคงที่ Java.lang.String java.lang.string.copyvalueof (char [], int, int) บูลีนสาธารณะ java.lang.string.endswith (java.lang สตริง) บูลีนสาธารณะ java.lang.string.equalsignorecase (java.lang.string) สาธารณะคงที่ java.lang.string java.lang.string.format (java.lang.string, java.lang.object [] .lang.string java.lang.st ring.format (java.util.locale, java.lang.string, java.lang.object []) ไบต์สาธารณะ [] java.lang.string.getBytes (java.lang.string ) พ่น java.io.unsupportenenc ordexceptionpublic เป็นโมฆะ java.lang getBytes (java.nio.charset.char Set) โมฆะสาธารณะ java .lang.string.getChars (int, int, char [], int) public พื้นเมือง java.lang.string java.lang.string.intern () บูลีน .lang.string.isempty () สาธารณะ int j ava.lang ) สาธารณะ int java.lan g.string.lastindexof (java.lang. String, int) สาธารณะ int java.lang.string.length () บูลีนสาธารณะ java.lang.string.matches (java.lang.string) สาธารณะ .lang.string.offsetbycodepoin ts (int, int) บูลีนสาธารณะ java.lang .string.regionmatches (บูลีน, int, java.lang.string, int, int, int) บูลีนสาธารณะ java.lang.string.regionmatches java.lang.string, int, int) สาธารณะ java.lan g.string java.lang .string.replace (java.lang.charequence, java.lang.charequence) สาธารณะ java.lang.string java.lang.string.string.replace (ถ่าน, ถ่าน) สาธารณะ java.lang.string java .lang.string.replaceall (java .lang.string, java.lang.string) สาธารณะ java.lang.string java.lang.string.replacefirst (java.lang.string.string , java.lang.string) สาธารณะ java.lang.string [] java.lan g.string .split (java.lang.string) สาธารณะ java.lang.string [] java.lang.string.split (java.lang สตริง, int) บูลีนสาธารณะ java.lang.string.startswith (java.lang.st แหวน) บูลีนสาธารณะ java.lang.string.startswith (java.lang.string, int) สาธารณะ java.lang. .Subeence (int, int) สาธารณะ java.lang.string J ava.lang.string.substring (int) สาธารณะ java.lang.string java.lang.string.substring (int, int) ถ่านสาธารณะ [] java.lang String.toChararray () สาธารณะ java.lang.string java.lang.string.tolow ercase () สาธารณะ Java .String java.lang.string.touppercase () สาธารณะ java.lang.String java.lang.string ing.touppercase (java.util. locale) สาธารณะ java.lang.string java.lang.string.trim () สาธารณะสุดท้าย โมฆะ java.lang.object.wait (ยาว) พ่น java.lang.interruptedexceptionpub lic สุดท้ายโมฆะ java.lang.object.wait () โยน java .lang java.lang.InterruptedExceptionPublic พื้นเมืองสุดท้าย java.lang.cla ss java.lang.object.getClass () สาธารณะสุดท้ายเป็นโมฆะ Java.lang.Object
แสดงรายการชื่อวิธีทั้งหมดอักขระ จำกัด ประเภทการส่งคืนและการโยนข้อยกเว้นของคลาส java.lang.string โปรแกรมนี้ใช้เมธอดคลาสคลาสคลาสเพื่อโหลดคลาสที่ระบุจากนั้นเรียกใช้เมธอด GetMethods เพื่อส่งคืนรายการวิธีการของคลาสที่ระบุ java.lang.reflect.method ใช้เพื่อแสดงวิธีเดียวในคลาสที่แน่นอน
การใช้กลไกการสะท้อนของ Java โดยทั่วไปต้องใช้สามขั้นตอน:
รับวัตถุคลาสที่คุณต้องการใช้งานคลาสผ่านวัตถุคลาสที่ได้รับในขั้นตอนแรกเพื่อรับวิธีการของคลาสหรือวิธีการหรือแอตทริบิวต์ที่ได้รับในขั้นตอนที่สองของการทำงานของชื่อคลาส
เมื่อ Java กำลังทำงานอยู่ไม่ว่าจะมีวัตถุจำนวนเท่าใดที่คลาสที่สร้างขึ้นก็จะสอดคล้องกับวัตถุคลาสเดียวกันซึ่งแสดงถึงคลาสและอินเทอร์เฟซในโปรแกรมการทำงาน如何取得操作类的Class对象,常用的有三种方式:
调用Class的静态方法forName,如上例;
使用类的.class语法,如:Class<?> cls = String.class;
调用对象的getClass方法,如:String str = "abc";Class<?> cls = str .getClass();
下面将通过实例讲述如何通过前面所诉的三步来执行某对象的某个方法:
package com.wanggc.reflection; import java.lang.reflect.Method; /** * Java 反射练习。 * * @author Wanggc */ Public Class ReflectionTest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) พ่นข้อยกเว้น {แสดงผล = จอแสดงผลใหม่ (); รับวิธีการแสดงของคลาสการแสดงผลผ่านวิธีการคลาส = cls.getmethod ("show", string.class); void show(String name) { System.out.println("Hello :" + name); } }前面说过,Java程序的每个类都会有个Class对象与之对应。 Java反射的第一步就是获得这个Class对象,如代码14行。当然,每个类的方法也必有一个Method对象与之对应。 ในการเรียกใช้วิธีนี้ผ่านการสะท้อนกลับคุณจะต้องได้รับวัตถุวิธีการของวิธีนี้เช่นบรรทัดที่ 16 ของรหัสจากนั้นใช้วัตถุวิธีการเรียกใช้วิธีนี้ในทางกลับกันเช่นบรรทัดที่ 18 ของรหัส โปรดทราบว่าพารามิเตอร์แรกของวิธี getMethod ในบรรทัดที่ 16 คือชื่อวิธีและที่สองคือประเภทพารามิเตอร์ของวิธีนี้ ดำเนินการวิธีการของการเรียกใช้รหัส 18 บรรทัดซึ่งเป็นวิธีการแสดง parameter is to pass it to the show method. parameters.类型和个数一定要与16行的getMethod方法一直。
ตัวอย่างข้างต้นแสดงวิธีการเรียกวิธีการของคลาสที่แน่นอนผ่านการสะท้อนกลับ
package com.wanggc.reflection; import java.lang.reflect.Field; /** * Java 反射之属性练习。 * * @author Wanggc */ Public Class ReflectionTest {โมฆะสาธารณะคงที่ (String [] args) โยนข้อยกเว้น {// สร้างนักเรียนวัตถุนักเรียน = นักเรียนใหม่ () // กำหนดนักเรียนวัตถุนักเรียน SetStuname ("Wanggc") นักเรียน. SetStuage (); ) + ":" + destStudent.getStuAge()); } /** * Copy student object information. * * @param จาก * คัดลอกวัตถุต้นทาง * @param dest * คัดลอกวัตถุเป้าหมาย * @throws Exception * Exception */ Private Static Void Copybean (Object จาก, Dest Object) โยนข้อยกเว้น {// รับวัตถุคลาสของการคัดลอก Source Object Class <?> fromclass = from.getClass (); > destclass = dest.getClass (); ชื่อของการคัดลอกวัตถุ destfield = destc lass.getdeclaredfield (ชื่อ); วัตถุไปยังแอตทริบิวต์ที่สอดคล้องกันของวัตถุเป้าหมายการคัดลอกวัตถุ destfield.set (dest, fromfield .:::::::::::::::::::::::::::::::::: กระทาน ::::::::::::::::::::::: กระทาน : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : get(from)) ; } } } /** * Student class. */ class Student { /** 姓名*/ private String stuName; /** 年龄*/ private int stuAge; /** * 获取学生姓名。 ** @return ชื่อนักเรียน*/ สตริงสาธารณะ getStuname () {return stuname;}/ *** ตั้งชื่อนักเรียน** @param stuname* ชื่อนักเรียน*/ โมฆะสาธารณะ setStuname } / *** รับนักเรียนอายุ** @return อายุนักเรียน* / public int getStuage () {return stuage; ) {this.stuage = Stuage;}}ในกลไกการเปิดตัว Java คลาสสอดคล้องกับคลาสวิธีการคลาสสอดคล้องกับวิธีการและแน่นอนคุณสมบัติยังสอดคล้องกับฟิลด์ ความคิดเห็นในรหัสได้รับการแสดงความคิดเห็นในรายละเอียดและจะไม่ถูกทำซ้ำที่นี่ แต่โปรดทราบว่าฟิลด์มีวิธีการรับและตั้งค่าเพื่อรับและตั้งค่าของแอตทริบิวต์ แต่เนื่องจากแอตทริบิวต์เป็นประเภทส่วนตัวการเข้าถึงแอตทริบิวต์จำเป็นต้องตั้งค่าเป็นจริงเช่นบรรทัด 50 ~ 51 ของ รหัส. นอกจากนี้คุณยังสามารถตั้งค่าการเข้าถึงสำหรับฟิลด์ทั้งหมดและใช้วิธีการคงที่ของ AccessibleObject SetAccessible ภายใต้ 40 บรรทัดเช่น: AccessibleObject.setAccessible (Frontfields, TRUE);
คำอธิบายก่อนหน้านี้แสดงวิธีการใช้กลไกการสะท้อน Java เพื่อใช้งานวิธีการและคุณสมบัติของคลาส
แพ็คเกจ com.wanggc.reflection; * * @author Wanggc */ Public Class ReflectionTest {โมฆะสาธารณะคงที่หลัก (String [] args) โยนข้อยกเว้น {// สร้างนักเรียนวัตถุนักเรียน = นักเรียนใหม่ () // กำหนดนักเรียนวัตถุนักเรียน SetStuname ("Wanggc") นักเรียน. SetStuage (); ());} /*** คัดลอกข้อมูลวัตถุนักเรียน * * @param จาก * คัดลอกวัตถุต้นทาง * @param dest * คัดลอกวัตถุเป้าหมาย * @throws Exception * Exception */ วัตถุคงที่ส่วนตัว copybean (วัตถุจาก) พ่นข้อยกเว้น {// รับการคัดลอกคลาสคลาสวัตถุของคลาสวัตถุแหล่งที่มา < ?> fromclass = from.getClass (); (); สำหรับ (FIELD FRIFIEL: FRANDS) {// ตั้งค่าการเข้าถึงแอตทริบิวต์ FRINTER.SETACCESSIBLE (TRUE); SET (ints, fromfield.get (จาก));} return ints; * / ชั้นเรียนนักเรียน { / ** ชื่อ* / สตริงส่วนตัว stuname; ** @return ชื่อนักเรียน*/ สตริงสาธารณะ getStuname () {return stuname;}/ *** ตั้งชื่อนักเรียน** @param stuname* ชื่อนักเรียน*/ โมฆะสาธารณะ setStuname } / *** รับนักเรียนอายุ** @return อายุนักเรียน* / public int getStuage () {return stuage; ) {this.stuage = Stuage;}}ผลลัพธ์ของตัวอย่างนี้และตัวอย่างก่อนหน้านี้เหมือนกัน อย่างไรก็ตามวัตถุที่ส่งคืนโดยวิธี CopyBean จะไม่ถูกส่งผ่านออกไปด้านนอกอีกต่อไป แต่ถูกสร้างขึ้นภายในโดยวิธีการดังที่แสดงในรหัสบนบรรทัดที่ 40 หมายเหตุ: วิธีการใหม่ของคลาสใหม่สามารถสร้างคลาสที่มีตัวสร้างโดยไม่มีพารามิเตอร์ wanggc ");
ณ จุดนี้ฟังก์ชั่นทั่วไปของกลไกการสะท้อน Java (วิธีการเรียกวัตถุที่รันไทม์ใช้แอตทริบิวต์คลาสและการสร้างวัตถุคลาส) ได้รับการแนะนำ
ภาคผนวก: เมื่อได้รับวิธีการคุณสมบัติและตัวสร้างของคลาสมีสองวิธีที่สอดคล้องกัน: getXXX และ getGetDeclaredxxx ความแตกต่างคือวิธีการส่งคืนและคุณสมบัติในอดีตที่มีสิทธิ์การเข้าถึงสาธารณะรวมถึงวิธีการในชั้นเรียนหลัก
เนื้อหาข้างต้นคือกลไกการเปิดตัว Java ที่แนะนำให้คุณรู้จักฉันหวังว่าคุณจะชอบ