นอกเหนือจากการให้ข้อมูลต่าง ๆ แก่เราเกี่ยวกับการเรียนในช่วงระยะเวลาการรวบรวมแล้ว Java ยังช่วยให้เราได้รับข้อมูลต่าง ๆ เกี่ยวกับชั้นเรียนในช่วงระยะเวลาการทำงานผ่านการสะท้อน ดึงข้อมูลคลาสผ่านการสะท้อนกลับและหลังจากได้รับข้อมูลชั้นเรียนคุณสามารถรับเนื้อหาที่เกี่ยวข้องต่อไปนี้:
บทความนี้จะแนะนำการสะท้อน Java จากด้านบน รหัสทั้งหมดที่เกี่ยวข้องในบทความนี้สะท้อนให้เห็น
ครั้งแรกคลาส Java จะถูกปล่อยออกมาเป็นวัตถุการวิจัยเพื่อการไตร่ตรอง เนื้อหาของชั้นเรียนมีดังนี้:
Public Public Class FatherObject ใช้งาน {โมฆะสาธารณะ dosomething () {system.out.println ("ทำสิ่งต่าง ๆ ... "); }} คลาสสาธารณะตัวอย่างตัวอย่างขยาย fatherObject {public int อายุ = 30; ชื่อสตริงสาธารณะ = "byhieg"; คะแนนจำนวนเต็มส่วนตัว = 60; โมฆะสาธารณะ printName () {system.out.println (ชื่อ); } public int getage () {return Age; } การตั้งค่าโมฆะสาธารณะ (อายุ int) {this.age = อายุ; } สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; } จำนวนเต็มสาธารณะ getScore () {คะแนนคืน; } โมฆะสาธารณะ setScore (คะแนนจำนวนเต็ม) {this.score = คะแนน; } public exampleObject () {} public exampleObject (ชื่อสตริง) {} public exampleObject (อายุ int, คะแนนจำนวนเต็ม) {} @Override โมฆะสาธารณะ dosomething () {super.dosomething (); } @Override โมฆะสาธารณะเรียกใช้ () {system.out.println ("เรียกใช้ ... "); -วัตถุชั้นเรียน
แอปพลิเคชั่นของเราจะใช้จุดสะท้อนความรู้ เราต้องต้องการรับข้อมูลของคลาสที่รันไทม์และดำเนินการเฉพาะบางอย่างตามข้อมูลของคลาส จากนั้นสิ่งแรกคือการรับข้อมูลของชั้นเรียนและวัตถุคลาสมีให้ใน JDK เพื่อบันทึกข้อมูลของชั้นเรียน ดังนั้นขั้นตอนแรกในการสะท้อนคือการได้รับวัตถุคลาส มีสองวิธีในการรับวัตถุคลาสใน JDK
อันแรกคือถ้าคุณรู้ชื่อของคลาสเมื่อเขียนโค้ดคุณสามารถรับวัตถุคลาสได้โดยตรงด้วยวิธีต่อไปนี้:
Class exampleObjectClass = ExampleObject.class;
ประเภทที่สองคือถ้าคุณไม่ทราบชื่อของคลาสเมื่อเขียนโค้ด แต่ที่รันไทม์คุณสามารถรับสตริงของชื่อคลาสและคุณสามารถรับวัตถุคลาสด้วยวิธีต่อไปนี้:
Class exampleObjectClass = Class.forName("cn.byhieg.reflectiontutorial.ExampleObject");
โปรดทราบว่าวิธีนี้ต้องมี 2 เงื่อนไข ก่อนอื่นสตริงในชื่อ forname จะต้องมีชื่อที่ผ่านการรับรองอย่างสมบูรณ์และที่สองคลาสคลาสจะต้องต่ำกว่าเส้นทางของ classpath เนื่องจากวิธีการจะโยนข้อยกเว้นของ classnotfoundexception
หลังจากได้รับวัตถุคลาสนี้คุณจะได้รับข้อมูลต่าง ๆ เกี่ยวกับชั้นเรียน ข้อมูลบางอย่างได้รับการกล่าวถึงในตอนแรก ด้านล่างเรามาพูดถึงข้อมูลเกี่ยวกับชั้นเรียนที่ยังไม่ได้กล่าวถึง
รับชื่อชั้นเรียน
มีสองวิธีในการรับชื่อของชั้นเรียนหนึ่งคือ getName () และอีกวิธีหนึ่งคือ getSimplename () คนแรกได้รับชื่อที่ผ่านการรับรองอย่างสมบูรณ์และชื่อที่สองได้รับชื่อของคลาสนี้โดยไม่มีชื่อแพ็คเกจ ดูตัวอย่างต่อไปนี้: วัตถุคลาสซึ่งได้รับผ่านรหัสด้านบน
String fullClassName = ExampleBjectClass.getName (); String SimpleClassName = ExampleObjectClass.getSimplename (); System.out.println (FullClassName); System.out.println (SimpleClassName); System.out.println (SimpleClassName);
ผลลัพธ์มีดังนี้:
cn.byhieg.reflectionTutorial.exampleObjectExampleObject
รับชื่อแพ็คเกจของคลาสคลาสแม่และอินเทอร์เฟซการใช้งาน
ชื่อแพ็คเกจและคลาสแม่ของคลาสสามารถรับได้ผ่านรหัสต่อไปนี้
// รับแพ็คเกจข้อมูลแพ็คเกจ apackage = exampleobjectclass.getPackage (); System.out.println (Apackage); // รับคลาสพาเรนต์คลาส superclass = exampleobjectclass.getsuperclass (); System.out.println (superclass.getSimplename ());
ผลลัพธ์มีดังนี้:
แพ็คเกจ cn.byhieg.reflectiontutorialfatherobject
เห็นได้ชัดว่าการได้รับค่าส่งคืนของคลาสแม่ก็เป็นวัตถุคลาส จากนั้นคุณสามารถใช้วัตถุนี้เพื่อรับข้อมูลบางอย่างเกี่ยวกับคลาสหลักเช่นการตัดสินว่าคลาสแม่เป็นคลาสนามธรรมหรือไม่
System.out.println("父类是不是抽象类" + Modifier.isAbstract(superClass.getModifiers()));
GetModifiers สามารถรับตัวดัดแปลงคลาสได้ดังนั้นจึงได้รับการดัดแปลงคลาส แน่นอนว่า getModifiers นี้ไม่เพียง แต่เรียกว่าวัตถุคลาสเท่านั้น แต่สามารถเรียกวัตถุวิธีการได้
คุณสามารถใช้วิธีการในคลาส java.lang.reflect.modifier เพื่อตรวจสอบประเภทของตัวดัดแปลง:
modifier.isabstract (int modifiers); modifier.isfinal (int modifiers); modifier.isinterface (int modifiers); modifier.isnative (int modifiers); modifier.isprivate (int modifier); ตัวดัดแปลง); modifier.Isstrict (int modifiers); modifier.issynchronized (int modifiers); modifier.istransient (Int modifiers); modifier.isvolatile (int modifiers);
นอกจากนี้เรายังสามารถรับอินเทอร์เฟซที่ใช้โดยคลาสแม่
// รับคลาสอินเตอร์เฟส [] คลาส = superclass.getInterfaces (); System.out.println ("อินเทอร์เฟซของคลาสแม่" + คลาส [0]);เนื่องจากคลาส Java สามารถใช้อินเทอร์เฟซจำนวนมากได้พวกเขาจึงใช้อาร์เรย์ แต่เมื่อใช้จริงคุณต้องกำหนดความยาวของอาร์เรย์ก่อน
ด้านล่างเราจะมุ่งเน้นไปที่การอธิบายเนื้อหาที่ระบุไว้ข้างต้น
ตัวสร้าง
การใช้ Java Reflection คุณจะได้รับตัวสร้างคลาสและสร้างวัตถุแบบไดนามิกที่รันไทม์ตามตัวสร้าง ก่อนอื่น Java ได้รับอินสแตนซ์ของตัวสร้างโดย:
// ConstructorConstructor [] constructors = exampleBjectClass.getConstructors (); สำหรับ (คอนสตรัคเตอร์คอนสตรัคเตอร์: ตัวสร้าง) {system.out.println (constructor.toString ()); -ผลลัพธ์มีดังนี้:
สาธารณะ cn.byhieg.reflectiontutorial.exampleObject (int, java.lang.integer) สาธารณะ cn.byhieg.reflectiontutorial.exampleObject (java.lang.string) สาธารณะ
หากคุณทราบประเภทพารามิเตอร์ของตัวสร้างเพื่อเข้าถึงล่วงหน้าคุณสามารถใช้วิธีการต่อไปนี้เพื่อรับตัวสร้างที่ระบุดังนี้:
Constructor Constructor = ExampleBjectClass.getConstructor (String.class); System.out.println (constructor.toString ());
เห็นได้ชัดว่าเป็นผล:
public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String)
ตัวสร้างอื่นสามารถรับได้ด้วยวิธีต่อไปนี้
Constructor Constructor = ExampleBjectClass.getConstructor (int.class, Integer.class); System.out.println (constructor.toString ());
นอกจากนี้หากเราไม่ทราบพารามิเตอร์ตัวสร้างและสามารถรับวัตถุตัวสร้างทั้งหมดได้เท่านั้นเราสามารถรับพารามิเตอร์ที่แต่ละคอนสตรัคเตอร์ใช้ดังนี้:
Constructor [] constructors = exampleobjectclass.getConstructors (); สำหรับ (คอนสตรัคเตอร์คอนสตรัคเตอร์: ตัวสร้าง) {คลาส [] พารามิเตอร์พารามิเตอร์ = constructor.getParameterTypes (); System.out.println ("พารามิเตอร์ตัวสร้างเป็น ติดตาม ============================================================================================= - สำหรับ (Class CLZ: ParameterTypes) {System.out.println ("ParameterType" + clz.toString ());}}ผลลัพธ์มีดังนี้:
พารามิเตอร์คอนสตรัคเตอร์มีดังนี้ ===================================== พารามิเตอร์ประเภทคลาส Java.lang พารามิเตอร์คอนสตรัคเตอร์สตริงมีดังต่อไปนี้ ===========================
ที่นี่จะเห็นได้ว่าวิธีการก่อสร้างที่ไม่มีพารามิเตอร์ไม่ได้พิมพ์ผลลัพธ์ วัตถุคลาสของประเภทพื้นฐานและวัตถุคลาสของประเภทการอ้างอิงนั้นแตกต่างกัน
ตอนนี้วัตถุสามารถสร้างได้แบบไดนามิกตามข้อมูลต่าง ๆ จากตัวสร้าง
Object Object = Constructor.NewInstance (1,100); System.out.println (Object.toString ());
มีสองเงื่อนไขสำหรับการสร้างวัตถุ ครั้งแรกถูกสร้างขึ้นผ่านตัวสร้างพารามิเตอร์ ประการที่สองคือวัตถุตัวสร้างจะต้องได้รับผ่าน GetConstructor ที่ส่งผ่านในข้อมูลพารามิเตอร์
เงื่อนไขแรกคือสำหรับวัตถุที่สามารถสร้างได้โดยไม่ต้องใช้วิธีการก่อสร้างพารามิเตอร์ไม่จำเป็นต้องได้รับวัตถุตัวสร้าง วัตถุคลาสเรียกใช้เมธอด newinstance () และสร้างวัตถุโดยตรง
เงื่อนไขที่สองคือวัตถุคอนสตรัคเตอร์จะต้องได้รับผ่านแบบฟอร์ม ExampleObjectClass.getConstructor (String.class); มันจะผิดที่จะได้รับอาร์เรย์คอนสตรัคเตอร์ผ่าน GetConstructors จากนั้นเรียกวัตถุคอนสตรัคเตอร์ที่ระบุเพื่อสร้างวัตถุใน JDK1.8 แต่ JDK1.6 เป็นเรื่องปกติ
ตัวแปร
การใช้ Java Reflection คุณสามารถรับข้อมูลตัวแปรของคลาสที่รันไทม์และคุณสามารถสร้างวัตถุและตั้งค่าตัวแปรตามวิธีข้างต้น ก่อนอื่นตัวแปรสาธารณะทั้งหมดจะได้รับโดยทำตามวิธีการต่อไปนี้:
ฟิลด์ [] ฟิลด์ = exampleobjectclass.getfields (); สำหรับ (ฟิลด์ฟิลด์: ฟิลด์) {system.out.println ("ตัวแปรคือ:" + field.toString ()); -ผลลัพธ์มีดังนี้:
ตัวแปรคือ: public int cn.byhieg.reflectiontutorial.exampleObject.age ตัวแปรคือ: public java.lang.string cn.byhieg.reflectiontutorial.exampleobject.name
เห็นได้ชัดว่าตัวแปรสาธารณะที่ได้รับทั้งหมดเป็นสาธารณะและไม่ได้รับคะแนนตัวแปรส่วนตัวข้างต้น
เช่นเดียวกับตัวสร้างที่ได้รับเราสามารถระบุชื่อพารามิเตอร์แล้วรับตัวแปรที่ระบุ:
Field Field = ExampleObjectClass.getField ("อายุ"); System.out.println ("ตัวแปรคือ:" + field.toString ());ชื่อที่ได้จากวิธีการ toString ของตัวแปรข้างต้นนั้นยาวเกินไป Java จัดเตรียมวิธี getName ไปยังคลาสฟิลด์ซึ่งส่งคืนชื่อของตัวแปรที่เขียนในคลาส รหัสข้างต้นสามารถเปลี่ยนเป็น field.getName ()
การสะท้อนไม่เพียง แต่ให้วิธีการรับตัวแปร แต่ยังมีวิธีการตั้งค่าตัวแปร โดยทำตามวิธีการต่อไปนี้คุณสามารถเปลี่ยนค่าตัวแปรของคลาสที่สร้างขึ้นแบบไดนามิก:
exampleObject object = ((ตัวอย่าง) constructor1.newinstance ("byhieg")); System.out.println ("อายุดั้งเดิมคือ" + Object.age); field.set (วัตถุ, 10); System.out.println ("อายุหลังจากการเปลี่ยนแปลงคือ" + object.age);ผลลัพธ์มีดังนี้:
อายุดั้งเดิมคือ 30 และอายุหลังจากการเปลี่ยนแปลงคือ 10
ตามรหัสด้านบนคุณสามารถรับวัตถุฟิลด์ชื่ออายุจากนั้นเรียกใช้วิธีการตั้งค่าของวัตถุส่งวัตถุและค่าที่จะเปลี่ยนแปลงจากนั้นคุณสามารถเปลี่ยนค่าของวัตถุ โปรดทราบว่าวิธีนี้ไม่เพียง แต่มีประโยชน์สำหรับตัวแปรสมาชิกเท่านั้น แต่ยังรวมถึงตัวแปรคงที่ แน่นอนถ้ามันเป็นตัวแปรคงที่มันก็โอเคที่จะผ่าน Null โดยไม่ผ่านวัตถุ
วิธี
นอกเหนือจากการให้ข้อมูลตัวแปรของชั้นเรียนแก่เราแล้ว Java Reflection ยังให้ข้อมูลวิธีการแก่เรา การสะท้อนกลับช่วยให้เราได้รับชื่อเมธอดพารามิเตอร์วิธีการประเภทการส่งคืนวิธีการและวิธีการโทร
ก่อนอื่นให้รับวิธีการผ่านรหัสต่อไปนี้:
// วิธีการสาธารณะของวิธีการคลาสเอาต์พุต [] methods = exampleBjectClass.getMethods (); สำหรับ (วิธีการ: วิธีการ) {system.out.println ("method ="+ method.getName ()); -รหัสที่ดูเหมือนคุ้นเคยกับการรับตัวแปร getName ถูกเรียกโดยตรงที่นี่เพื่อรับชื่อวิธีที่เขียนในชั้นเรียน เมื่อเขียนสิ่งนี้คุณควรคิดว่า Java ยังให้วิธีการเฉพาะตามพารามิเตอร์
Method Method = ExampleBjectClass.getMethod ("setage", int.class); System.out.println (method.getName ());ความแตกต่างที่นี่คือวิธีการ getMethod ยังต้องส่งผ่านข้อมูลประเภทพารามิเตอร์การสะท้อนให้วิธีการรับพารามิเตอร์วิธีการและประเภทการส่งคืน ตัวอย่างของการรับพารามิเตอร์วิธีการมีดังนี้:
Method Method = ExampleBjectClass.getMethod ("setage", int.class); System.out.println (method.getName ()); สำหรับ (Class clz: method.getParameterTypes ()) {system.out.println ("พารามิเตอร์ของเมธอด" + clz.getName ()); -ผลลัพธ์มีดังนี้:
พารามิเตอร์ int ของวิธีการตั้งค่า
ตัวอย่างของการได้รับวิธีการส่งคืนวิธีการดังนี้:
System.out.println(method.getReturnType().getName());
ผลลัพธ์มีดังนี้:
void
นอกจากนี้ Java Reflection ยังสนับสนุนวิธีการที่ได้จากการเรียกใช้ ตัวอย่างมีดังนี้:
method.invoke(exampleObjectClass.newInstance(),1);
พารามิเตอร์แรกที่เรียกใช้คือวัตถุนี้และพารามิเตอร์ที่สองเป็นอาร์เรย์ความยาวตัวแปรและพารามิเตอร์ของวิธีการผ่านเช่นวัตถุฟิลด์สำหรับวิธีการคงที่คุณสามารถผ่านวิธีการที่เป็นโมฆะและเรียกใช้วิธีคงที่
ตัวแปรส่วนตัวและวิธีการส่วนตัว
วิธีการข้างต้นสามารถรับวิธีการสาธารณะและตัวแปรเท่านั้น แต่ไม่สามารถรับวิธีการและตัวแปรที่ไม่ได้รับการแก้ไข Java จัดเตรียมวิธีการเพิ่มเติมเพื่อให้ได้ตัวแปรและวิธีการที่ไม่ใช่แบบสาธารณะ นั่นคือตัวแปรส่วนตัวและวิธีการที่ได้รับผ่านวิธี getDeclaredFields และ getDeclaredMethods นอกจากนี้ยังรองรับการใช้ GetDeclaredField (ชื่อตัวแปร) และ getDeclaredMethod (ชื่อวิธี) เพื่อรับชื่อตัวแปรที่ระบุและชื่อวิธี อย่างไรก็ตามวัตถุฟิลด์และวัตถุวิธีการที่ได้รับในวิธีนี้ไม่สามารถใช้โดยตรง วัตถุเหล่านี้จะต้องเรียกว่า setAccessible (จริง) สำหรับการใช้งานปกติ วิธีการต่อไปนี้อาจเป็นเช่นเดียวกับที่กล่าวไว้ข้างต้น
คำอธิบายประกอบ
ก่อนเขียนชั้นเรียนที่มีคำอธิบายประกอบ:
@myannotation (name = "byhieg", value = "hello world") AnnotationObject คลาสสาธารณะ {@myannotation (name = "field", value = "ตัวแปร") ฟิลด์สตริงสาธารณะ; @myannotation (name = "method", value = "method") โมฆะสาธารณะ dosomething () {system.out.println ("ทำอะไรบางอย่าง"); } โมฆะสาธารณะ dootherthing (@myannotation (name = "param", value = "param") พารามิเตอร์สตริง) {}}@retention (RetentionPolicy.runtime) สาธารณะ @interface myannotation {ชื่อสตริงสาธารณะ (); ค่าสตริงสาธารณะ ();}Java ให้ข้อมูลเกี่ยวกับการได้รับคำอธิบายประกอบชั้นเรียนที่รันไทม์และเราสามารถรับคำอธิบายประกอบชั้นเรียนคำอธิบายประกอบของวิธีการคำอธิบายประกอบพารามิเตอร์และคำอธิบายประกอบตัวแปร
เช่นเดียวกับวิธีการซื้อกิจการข้างต้น Java มีวิธีการซื้อสองวิธี หนึ่งคือการได้รับคำอธิบายประกอบทั้งหมดและส่งคืนอาร์เรย์และที่สองคือการระบุคำอธิบายประกอบที่ระบุ
ลองใช้คำอธิบายประกอบชั้นเรียนเป็นตัวอย่างเพื่ออธิบายสองวิธีต่อไปนี้
Class clz = AnnotationObject.class; คำอธิบายประกอบ [] คำอธิบายประกอบ = clz.getannotations (); คำอธิบายประกอบคำอธิบายประกอบ = clz.getannotation (AnnotationObject.class);
จากนั้นการประมวลผลที่ตามมาสามารถทำได้ตามคำอธิบายประกอบที่ได้รับ ต่อไปนี้เป็นตัวอย่างของการประมวลผล:
สำหรับ (คำอธิบายประกอบคำอธิบายประกอบ: คำอธิบายประกอบ) {ถ้า (คำอธิบายประกอบของ myannotation) {myannotation myannotation = (myannotation) คำอธิบายประกอบ; System.out.println ("ชื่อ:" + myannotation.name ()); System.out.println ("ค่า:" + myannotation.value ()); -คำอธิบายประกอบคลาสข้างต้นได้มาจากการเรียก getannotations โดยใช้วัตถุคลาส คำอธิบายประกอบของวิธีการและคำอธิบายประกอบตัวแปรเหมือนกัน ฉันเรียก getDeclaredAnnotations โดยใช้วัตถุวิธีและวัตถุฟิลด์ตามลำดับเพื่อรับคำอธิบายประกอบ ฉันไม่ได้พูดอะไรมากมาย ดูตัวอย่างรหัสสะท้อน
คำอธิบายประกอบพารามิเตอร์เป็นรายการที่ค่อนข้างลำบาก วิธีการซื้อกิจการถูกเปรียบเทียบ ขั้นตอนแรกคือการรับวัตถุวิธีการก่อนและเรียก getParameterannotations อย่างไรก็ตามค่าการส่งคืนนี้เป็นอาร์เรย์สองมิติเนื่องจากวัตถุเมธอดมีพารามิเตอร์จำนวนมากและแต่ละพารามิเตอร์อาจมีคำอธิบายประกอบจำนวนมาก ตัวอย่างมีดังนี้:
Method Method1 = clz.getMethod ("dootherthing", string.class); คำอธิบายประกอบ [] [] AnnotationInparam = method1.getParameterannotations (); คลาส [] params = method1.getParameterTypes (); int i = 0; สำหรับ (คำอธิบายประกอบ [] คำอธิบายประกอบ: AnnotationInparam) {class para = params [i ++]; สำหรับ (คำอธิบายประกอบคำอธิบายประกอบ: คำอธิบายประกอบ) {ถ้า (คำอธิบายประกอบของ myannotation) {myannotation myannotation = (myannotation) คำอธิบายประกอบ; System.out.println ("param:" + para.getName ()); System.out.println ("ชื่อ:" + myannotation.name ()); System.out.println ("ค่า:" + myannotation.value ()); -เรื่องสั้น
เนื่องจาก Java Generics ถูกนำไปใช้ผ่านการลบจึงเป็นเรื่องยากที่จะได้รับข้อมูลโดยตรงเกี่ยวกับประเภทพารามิเตอร์เฉพาะของยาชื่อสามัญ แต่เราสามารถรับข้อมูลทั่วไปผ่านรูปแบบทางอ้อมโดยใช้การสะท้อนกลับ ตัวอย่างเช่นคลาสต่อไปนี้:
Public Class GenericObject {รายการสาธารณะ <String> รายการ; รายการสาธารณะ <String> getLists () {รายการส่งคืน; } public void setlists (รายการ <String> รายการ) {this.lists = รายการ; -หากวิธีการส่งคืนคลาสทั่วไปเราสามารถเรียก getGenericReturntype ผ่านวัตถุวิธีการไปยัง getGenericReturntype เพื่อรับสิ่งที่พารามิเตอร์เฉพาะของคลาสทั่วไปนี้คือ ดูรหัสต่อไปนี้:
คลาส clz = genericobject.class; วิธีการ = clz.getMethod ("getLists"); พิมพ์ genictype = method.getGenericReturnType (); if (อินสแตนซ์ทั่วไปของ parameterizedType) {parameterizedType parameterizedType = ((parameterizedType) generictype); ประเภท [] type = parameterizedType.getActualTuterGuments (); สำหรับ (ประเภทประเภท: ประเภท) {คลาส realclz = ((คลาส) ประเภท); System.out.println ("ประเภทการกำหนดค่าพารามิเตอร์คือ:" + realclz); -ผลลัพธ์มีดังนี้:
参数化类型为: class java.lang.String
ขั้นตอนนั้นยุ่งยากเล็กน้อยดังนั้นคำอธิบายต่อไปนี้คือ:
ฉันได้รับข้อมูลเฉพาะเกี่ยวกับยาชื่อสามัญโดยดูผลลัพธ์
หากไม่มีวิธีการส่งคืนประเภททั่วไปเรายังสามารถรับประเภทพารามิเตอร์ของประเภททั่วไปโดยพารามิเตอร์ของวิธีการเป็นคลาสทั่วไปเช่นวิธีการ setlists ในคลาสข้างต้น ตัวอย่างมีดังนี้:
วิธีการ setMethod = clz.getMethod ("setlists", list.class); พิมพ์ [] GenericParameterTypes = setMethod.GetGenericParameterTypes (); สำหรับ (ประเภท GenericParameterType: GenericParameterTypes) {System.out.println ("GenericParameterTypes คือ:" + GenericParametertype.getTypename ()); if (อินสแตนซ์ทั่วไปของ ParameterizedType) {parameterizedType parameterizedType = ((parameterizedType) GenericParameterType); System.out.println ("ParameterizedType คือ:" + parameterizedType.getTypename ()); ประเภทประเภท [] = parameterizedType.getActualTuterGuments (); สำหรับ (ประเภทประเภท: ประเภท) {system.out.println ("ประเภทพารามิเตอร์คือ:" + ((คลาส) ประเภท) .getName ()); -ผลการดำเนินการมีดังนี้:
GenericParametertypes คือ: java.util.list <java.lang.string> parameterizedType คือ: java.util.list <java.lang.string> ประเภทพารามิเตอร์คือ: java.lang.string
เนื่องจากพารามิเตอร์ของวิธีการอาจมีมากกว่าหนึ่งประเภททั่วไปเรา getGenericParametertypes เพื่อรับอาร์เรย์และเราจำเป็นต้องพิจารณาว่าแต่ละองค์ประกอบมีประเภทพารามิเตอร์หรือไม่ ขั้นตอนที่ตามมานั้นคล้ายกับที่ข้างต้นดังนั้นฉันจะไม่พูดอะไรมาก
หากแม้แต่พารามิเตอร์เมธอดไม่มีคลาสทั่วไปแล้วกรณีสุดท้ายเท่านั้นที่เหลืออยู่ผ่านประเภทตัวแปรนั่นคือคลาสฟิลด์จะถูกใช้ ตัวอย่างมีดังนี้:
ฟิลด์ฟิลด์ = clz.getfield ("รายการ"); type type = field.getGenericType (); if (ประเภทอินสแตนซ์ของ parameterizedType) {parameterizedType parameterizedType = ((parameterizedType) ประเภท); ประเภท [] type = parameterizedType.getActualTuterGuments (); สำหรับ (type 1: ประเภท) {system.out.println ("ประเภทพารามิเตอร์:" + ((คลาส) type1) .getTypename ()); -หลักการนั้นเหมือนกับข้างต้นยกเว้นว่าวัตถุประเภทนั้นผ่าน field.getGenericType () ดังนั้นฉันจะไม่พูดมากเกี่ยวกับการดำเนินการที่เหลือ
นี่คือการแนะนำเพื่อให้ได้รับพารามิเตอร์ประเภททั่วไปผ่านการสะท้อน
อาร์เรย์
Java Reflection สามารถทำงานบนอาร์เรย์รวมถึงการสร้างอาร์เรย์การเข้าถึงค่าในอาร์เรย์และรับวัตถุคลาสของอาร์เรย์
มาพูดถึงเรื่องนี้ง่ายๆการสร้างอาร์เรย์และเข้าถึงค่าในอาร์เรย์: การใช้คลาสอาร์เรย์ในการสะท้อนกลับเป็นหนึ่งด้านล่างแพ็คเกจสะท้อนกลับ
// สร้างอาร์เรย์ของประเภท int ที่มีความยาว 3 int [] intarray = (int []) array.newinstance (int.class, 3); // กำหนดค่าให้กับอาร์เรย์ผ่านการสะท้อนกลับสำหรับ (int i = 0; i <intarray.length; i ++) {array.set (intarray, i, i+2); } // อาร์เรย์ในรูปแบบของการสะท้อนรับค่าในอาร์เรย์สำหรับ (int i = 0; i <intarray.length; i ++) {system.out.println (array.get (intarray, i)); -ด้านบนคือการสร้างอาร์เรย์และเข้าถึงค่าในอาร์เรย์โดยใช้การสะท้อนกลับ
สำหรับวัตถุคลาสที่ได้รับอาร์เรย์คุณสามารถใช้ int []. คลาส หรือใช้คลาส forName ซึ่งเป็นวิธีที่แปลกในการเขียน:
คลาส clz = class.forname ("[i"); System.out.println (clz.getTypename ());ผลที่ได้คือ:
int[]
สตริงในชื่อ forname นี้ [ หมายถึงอาร์เรย์ ฉัน เป็นตัวแทนของ int, float คือ f , double is d ฯลฯ หากคุณต้องการได้รับอาร์เรย์ของวัตถุธรรมดาให้ใช้แบบฟอร์มต่อไปนี้:
Class stringClz = Class.forName("[Ljava.lang.String;");
[ บอกว่ามันเป็นอาร์เรย์ด้านขวาของ L คือชื่อชั้นเรียนและด้านขวาของประเภทคือ A ; -
วิธีนี้ในการรับวัตถุคลาสของอาร์เรย์นั้นยุ่งยากเกินไป
หลังจากได้รับวัตถุคลาสของอาร์เรย์วิธีการที่ไม่ซ้ำกันบางอย่างสามารถเรียกได้เช่นการเรียก getComponentType เพื่อรับข้อมูลประเภทของสมาชิกอาร์เรย์ ตัวอย่างเช่นอาร์เรย์ int เป็นประเภทสมาชิกซึ่งเป็น int
System.out.println(clz.getComponentType().getTypeName());
ผลลัพธ์คือ int
สรุป
เวลานี้แอปพลิเคชันที่หลากหลายของการสะท้อนกลับจบลงด้วยสิ่งนี้และอาจมีคำอธิบายความรู้เชิงลึกในอนาคต สำหรับรหัสเฉพาะคุณสามารถดูรหัสสะท้อนแสง
ในแพ็คเกจ SRC มีคลาสที่หลากหลายและในคลาสทดสอบมันคือการเข้าถึงคลาสเหล่านี้
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะช่วยในการศึกษาหรือทำงานของทุกคน ฉันหวังว่าจะสนับสนุน Wulin.com เพิ่มเติม!