(1) ประเภทอินเทอร์เฟซที่เกี่ยวข้องกับการสะท้อนกลับ + ข้อมูลทั่วไป
java.lang.reflect.Type: อินเทอร์เฟซหลักทั่วไปสำหรับทุกประเภทในภาษาจาวา
java.lang.reflect.ParameterizedType
java.lang.reflect.GenericArrayType
java.lang.reflect.WildcardType
1. พิมพ์อินเทอร์เฟซย่อยโดยตรง
อินเทอร์เฟซสี่ประเภท: ParameterizedType, GenericArrayType, TypeVariable และ WildcardType
parameterizedType: แสดงถึงประเภทที่กำหนดพารามิเตอร์ เช่น คอลเลกชัน
GenericArrayType: หมายถึงประเภทอาร์เรย์ที่มีประเภทองค์ประกอบเป็นประเภทที่กำหนดพารามิเตอร์หรือตัวแปรประเภท
TypeVariable: เป็นอินเทอร์เฟซหลักทั่วไปสำหรับตัวแปรประเภทต่างๆ
WildcardType: แสดงถึงนิพจน์ประเภท wildcard เช่น ?, ? ขยายจำนวน ? super Integer [wildcard คือคำ: มันคือ "wildcard"]
2. พิมพ์คลาสย่อยที่ใช้โดยตรง: คลาสคลาส
3. อินเทอร์เฟซ java.lang.reflect.Type
ประเภททุกประเภทอ้างอิงถึง: ประเภทดิบ (ประเภทดิบ) [สอดคล้องกับคลาส], ประเภทที่กำหนดพารามิเตอร์ (ประเภทที่มีพารามิเตอร์) [สอดคล้องกับประเภทพารามิเตอร์] ประเภทอาร์เรย์ (ประเภทอาร์เรย์) [สอดคล้องกับ GenericArrayType] ตัวแปรประเภท (ตัวแปรประเภท) [ สอดคล้องกับ TypeVariable ], ประเภทข้อมูลพื้นฐาน (ประเภทดั้งเดิม) [ยังคงสอดคล้องกับคลาส]
4. อินเทอร์เฟซ java.lang.reflect.ParameterizedType
ความหมายของประเภทอินเทอร์เฟซ ParameterizedType
แสดงถึงประเภทที่กำหนดพารามิเตอร์ ตัวอย่างเช่น: ประเภทที่กำหนดพารามิเตอร์ เช่น แผนที่
รับประเภทจริงในประเภทพารามิเตอร์<>
คำสั่งซอร์สโค้ด: Type[] getActualTypeArguments();
[หมายเหตุ] ไม่ว่า <> การซ้อนใน <> จะมีกี่ระดับก็ตาม เมธอดนี้จะลบเฉพาะ <> ภายนอกสุดเท่านั้น และเนื้อหาที่เหลือจะถูกใช้เป็นค่าส่งคืนของเมธอดนี้
วิธีการ E คงที่สาธารณะ IV (
อาร์เรย์รายการ> al1,
อาร์เรย์รายการ al2,
อาร์เรย์รายการ al3,
อาร์เรย์รายการสิ้นสุดหมายเลข> al4,
ArrayList al5){}
โดยทั่วไปแล้วพารามิเตอร์แต่ละตัวจะเป็นประเภทพารามิเตอร์
{1} สำหรับ ArrayList> หลังจากส่งคืนผ่าน getActualTypeArguments() หลังจากลบ <> ภายนอกสุด ประเภทที่เหลือจะเป็น ArrayList ดังนั้นชนิดการส่งคืนสำหรับพารามิเตอร์นี้คือ parameterizedType
{2} สำหรับ ArrayList หลังจากส่งคืนผ่าน getActualTypeArguments() หลังจากลบส่วนนอกสุด <> แล้ว ประเภทที่เหลือจะเป็น E ดังนั้นชนิดการส่งคืนสำหรับพารามิเตอร์นี้คือ TypeVariable
{3} สำหรับ ArrayList หลังจากส่งคืนผ่าน getActualTypeArguments() หลังจากลบส่วนนอกสุด <> แล้ว ประเภทที่เหลือจะเป็น String ดังนั้นชนิดส่งคืนสำหรับพารามิเตอร์นี้คือคลาส
{4} สำหรับ ArrayListextends Number> หลังจากส่งคืนผ่าน getActualTypeArguments() หลังจากลบส่วนนอกสุด <> แล้ว ประเภทที่เหลือจะเป็น? ดังนั้นชนิดการส่งคืนสำหรับพารามิเตอร์นี้คือ WildcardType
{5} สำหรับ ArrayList หลังจากส่งคืนผ่าน getActualTypeArguments() หลังจากลบ <> ภายนอกสุด ประเภทที่เหลือจะเป็น E[] ดังนั้นประเภทการส่งคืนสำหรับพารามิเตอร์นี้คือ GenericArrayType
ดังนั้นจึงเป็นไปได้ที่จะได้รับพารามิเตอร์จริงประเภทต่างๆ ดังนั้นเพื่อประโยชน์ในการรวมเข้าด้วยกัน จึงมีการใช้อาร์เรย์คลาสพาเรนต์โดยตรง Type[] สำหรับการรับ
4. อินเทอร์เฟซ java.lang.reflect.GenericArrayType
ความหมายของประเภทอินเทอร์เฟซ GenericArrayType
แสดงถึงประเภทอาร์เรย์ทั่วไป ตัวอย่างเช่น: วิธีการเป็นโมฆะ(ArrayList[] al){…}
[หมายเหตุ] <> ไม่สามารถปรากฏในการเริ่มต้นของอาร์เรย์ กล่าวคือ <> ไม่สามารถปรากฏหลังจากอาร์เรย์ใหม่ มิฉะนั้น javac จะไม่ผ่าน แต่มันก็ใช้ได้ดีในฐานะตัวแปรอ้างอิงหรือพารามิเตอร์ของวิธีการ
รับประเภทขององค์ประกอบในอาร์เรย์ทั่วไป
การประกาศซอร์สโค้ด: พิมพ์ getGenericComponentType();
[หมายเหตุ] ไม่ว่าจะวาง [] จำนวนเท่าใดจากซ้ายไปขวา วิธีการนี้จะลบเฉพาะ [] ทางด้านขวาสุดออกเท่านั้น และเนื้อหาที่เหลือจะถูกใช้เป็นค่าส่งคืนของวิธีนี้
เหตุใดค่าส่งคืนจึงเป็นประเภท Type?
สาธารณะ E methodV แบบคงที่ (สตริง [] p1, E [] p2, ArrayList [] p3, E [] [] p4) {}{1} สำหรับ String[] หลังจากส่งคืนผ่าน getComponentType() หลังจากลบ [ขวาสุด] แล้ว ประเภทที่เหลือจะเป็น String ดังนั้นชนิดส่งคืนสำหรับพารามิเตอร์นี้คือคลาส
{2} สำหรับ E[] หลังจากส่งคืนผ่าน getComponentType() หลังจากลบด้านขวาสุด [] แล้ว ประเภทที่เหลือคือ E ดังนั้นชนิดการส่งคืนสำหรับพารามิเตอร์นี้คือ TypeVariable
{3} สำหรับ ArrayList[] หลังจากส่งคืนผ่าน getComponentType() หลังจากลบ [ทางขวาสุด] แล้ว ประเภทที่เหลือจะเป็น ArrayList ดังนั้นชนิดการส่งคืนสำหรับพารามิเตอร์นี้คือ parameterizedType
{4} สำหรับ E[][] หลังจากส่งคืนผ่าน getComponentType() หลังจากลบ [ ขวาสุดออกแล้ว ] ประเภทที่เหลือคือ E[] ดังนั้นประเภทการส่งคืนสำหรับพารามิเตอร์นี้คือ GenericArrayType
5. อินเทอร์เฟซ java.lang.reflect.GenericArrayType
ความหมายของประเภทอินเทอร์เฟซ TypeVariable
แสดงถึงพารามิเตอร์ประเภทหรือเรียกอีกอย่างว่าตัวแปรประเภท ตัวอย่างเช่น: E in void method(E e){} เป็นตัวแปรประเภท
รับประเภทของขอบเขตบนที่ผ่านการรับรองทั่วไปของตัวแปรประเภท
คำสั่งซอร์สโค้ด: Type[] getActualTypeArguments();
[หมายเหตุ] นี่เป็นเพียงขอบเขตบนเท่านั้น เหตุผลก็คือตัวแปรประเภทนั้นสามารถใช้ได้เฉพาะการขยายเพื่อจำกัดขอบเขต (หลายขอบเขต) เมื่อถูกกำหนดไว้เท่านั้น ไม่สามารถใช้ Super ได้ ไม่เช่นนั้นการคอมไพล์จะไม่ผ่าน ในเวลาเดียวกัน การขยายจะให้ขอบเขตบนของตัวแปรชนิด
เหตุใดประเภทการส่งคืนจึงเป็นอาร์เรย์ เนื่องจากตัวแปรประเภทสามารถกำหนดขอบเขตด้วยขอบเขตบนหลายรายการด้วย & จึงมีขอบเขตบนหลายรายการ ดังนั้นประเภทค่าที่ส่งคืนจึงเป็นประเภทอาร์เรย์ [ ]
ตัวอย่างเช่นวิธีการต่อไปนี้:
สาธารณะคงที่ขยายแผนที่ & โคลนและซีเรียลไลซ์ได้> E methodVI (E e) {…}ขอบเขตบนแรกของ E คือ Map ซึ่งเป็นประเภท parameterizedType
ขอบเขตบนที่สองของ E คือ Cloneable ซึ่งเป็นประเภทคลาส
ดังนั้นสำหรับการรวมประเภทองค์ประกอบของอาร์เรย์ของค่าที่ส่งคืนคือ Type
6. อินเทอร์เฟซ java.lang.reflect.WildcardType
ความหมายของประเภทอินเทอร์เฟซ WildcardType
นิพจน์ที่แสดงถึงประเภทไวด์การ์ด
ตัวอย่างเช่น ? ขยาย Number ใน void printColl(ArrayListal);
[หมายเหตุ] ตามความคิดเห็นของ API ข้างต้น: ในขั้นตอนนี้ นิพจน์ไวด์การ์ดจะยอมรับขอบเขตบนหรือขอบเขตล่างเพียงขอบเขตเดียวเท่านั้น ซึ่งแตกต่างจากขอบเขตบนหลายขอบเขตที่สามารถระบุได้เมื่อกำหนดตัวแปรประเภท แต่ API บอกว่าเพื่อรักษาความสามารถในการปรับขนาด ประเภทค่าตอบแทนที่นี่จะถูกเขียนในรูปแบบของอาร์เรย์ ที่จริงแล้ว ขนาดของอาร์เรย์ที่ส่งคืนตอนนี้คือ 1
รับชนิดของขอบเขตบนที่มีคุณสมบัติทั่วไปของออบเจ็กต์นิพจน์ไวด์การ์ด
คำสั่งซอร์สโค้ด: Type[] getUpperBounds();
[หมายเหตุ] ตามที่กล่าวไว้ข้างต้น ขนาดของอาร์เรย์ใน Type[] ที่ส่งคืนในขั้นตอนนี้คือ 1 เขียนเป็น Type[ ] เป็นส่วนเสริมสำหรับการอัปเกรดภาษา
ตัวอย่างเช่นวิธีการต่อไปนี้:
{1} voidprintColl สาธารณะแบบคงที่ (ArrayListextends ArrayList> al){}
นิพจน์ไวด์การ์ดคือ: ? extendsArrayList ดังนั้นส่วนขยายจะตามด้วยขอบเขตบนของ ? และขอบเขตบนนี้เป็นประเภท parameterizedType
{2} voidprintColl สาธารณะแบบคงที่ (ArrayListextends E> อัล){}
นิพจน์ตัวแทนคือ: ? ขยาย E ดังนั้นส่วนขยายจะตามด้วยขอบเขตบนของ ? และขอบเขตบนนี้เป็นประเภท TypeVariable
{3}.public voidprintColl แบบคงที่ (ArrayListext สิ้นสุด E[]> อัล){}
นิพจน์ไวด์การ์ดคือ: ? ขยาย E[] ดังนั้นส่วนขยายนั้นจึงตามด้วยขอบเขตบนของ ? และขอบเขตบนนี้เป็นประเภท GenericArrayType
{4}.public voidprintColl แบบคงที่ (หมายเลข ArrayListextends> อัล){}
นิพจน์ตัวแทนคือ: ? ขยาย Number ดังนั้นส่วนขยายจึงตามด้วยขอบเขตบนของ ? และขอบเขตบนนี้เป็นประเภทคลาส
ในที่สุดก็รวมเป็น Type เป็นประเภทองค์ประกอบของอาร์เรย์
7. ต้นกำเนิดของ Type และอินเทอร์เฟซย่อย
1. ประเภทก่อนการเกิดขึ้นของยาชื่อสามัญ
เมื่อไม่มียาชื่อสามัญ ก็มีเพียงสิ่งที่เรียกว่ายาสามัญเท่านั้น ในเวลานี้ ประเภทดั้งเดิมทั้งหมดจะถูกนามธรรมผ่านคลาสไฟล์ bytecode คลาสคลาส วัตถุที่เป็นรูปธรรมของคลาสคลาสแสดงถึงประเภทดั้งเดิมที่ระบุ
2. ประเภทภายหลังการเกิดขึ้นของยาชื่อสามัญ
หลังจากการเกิดขึ้นของยาชื่อสามัญ ชนิดข้อมูลก็ถูกขยายออกไป จากประเภทดั้งเดิมเท่านั้น ประเภทที่กำหนดพารามิเตอร์ ประเภทตัวแปร ประเภทประเภทพารามิเตอร์ที่มีคุณสมบัติทั่วไป (รวมถึงไวด์การ์ด + นิพจน์ที่ผ่านการรับรองไวด์การ์ด) และประเภทอาร์เรย์ทั่วไปได้รับการขยาย
3. สาเหตุที่ไม่สามารถรวมประเภทที่เกี่ยวข้องกับยาชื่อสามัญกับประเภทดั้งเดิมลงในคลาสได้
[1]. [สาเหตุของการลบข้อมูลทั่วไป]
เดิมทีประเภทที่สร้างขึ้นใหม่ + ประเภทดั้งเดิมควรถูกรวมเข้ากับออบเจ็กต์ประเภทไฟล์ bytecode ที่เกี่ยวข้อง แต่เนื่องจากยาชื่อสามัญไม่ใช่ส่วนประกอบใน Java แต่เดิม หากมีการเพิ่มยาชื่อสามัญจริง ๆ จะเกี่ยวข้องกับการดัดแปลงชุดคำสั่ง JVM ซึ่งเป็นอันตรายถึงชีวิตมาก
[2] [วิธีการแนะนำยาสามัญใน Java]
เพื่อที่จะใช้ประโยชน์จากยาชื่อสามัญโดยไม่ต้องแนะนำยาเหล่านี้จริงๆ Java จะใช้กลไกการลบข้อมูลทั่วไปเพื่อแนะนำยาชื่อสามัญ ข้อมูลทั่วไปใน Java ถูกใช้โดยคอมไพเลอร์ javac เท่านั้นเพื่อให้มั่นใจในความปลอดภัยของข้อมูลและหลีกเลี่ยงปัญหาในการแปลงประเภทบังคับ อย่างไรก็ตาม เมื่อการรวบรวมเสร็จสิ้น ทุกประเภทที่เกี่ยวข้องกับยาชื่อสามัญจะถูกลบออก
[3] [ชั้นเรียนไม่สามารถแสดงประเภทที่เกี่ยวข้องกับยาสามัญได้]
ดังนั้นประเภทที่กำหนดพารามิเตอร์ที่เกี่ยวข้องกับข้อมูลทั่วไป ประเภทตัวแปรประเภท ประเภทที่กำหนดพารามิเตอร์ทั่วไป (รวมถึงนิพจน์ที่ผ่านการรับรองไวด์การ์ด + นิพจน์ที่ผ่านการรับรองไวด์การ์ด) และประเภทอาเรย์ทั่วไปทั้งหมดจะถูกส่งกลับไปยังรูปแบบดั้งเดิมและถูกจัดเก็บไว้ในไฟล์ bytecode ทั้งหมดเป็นประเภทดั้งเดิม หลังจากลบข้อมูลทั่วไปแล้ว และไม่มีไฟล์ bytecode ที่สอดคล้องกับประเภทของมันเอง ดังนั้นประเภทที่ขยายใหม่ที่เกี่ยวข้องกับยาชื่อสามัญจึงไม่สามารถรวมเข้ากับคลาสคลาสได้
(4) การแสดงประเภทที่เกี่ยวข้องกับยาชื่อสามัญใน Java
เพื่อที่จะดำเนินการประเภทเหล่านี้ผ่านการสะท้อนกลับเพื่อตอบสนองความต้องการในการพัฒนาจริง Java ได้เพิ่ม parameterizedtype, GenericArrayType, TypeVariable และ WildcardType เพื่อแสดงประเภทที่ไม่สามารถจำแนกเป็นคลาสคลาสได้ แต่มีชื่อเดียวกันกับประเภทดั้งเดิม
(5) การแนะนำประเภท: การรวมประเภทที่เกี่ยวข้องกับคลาสยาสามัญและคลาสดั้งเดิม
[เหตุผลในการแนะนำประเภท]
สำหรับความสามารถในการปรับขนาดของโปรแกรม ในที่สุดอินเทอร์เฟซ Type ก็ถูกนำมาใช้เป็นอินเทอร์เฟซหลักทั่วไปสำหรับ Class, ParameterizedType, GenericArrayType, TypeVariable และ WildcardType ด้วยวิธีนี้ พารามิเตอร์ Type type ยอมรับพารามิเตอร์ที่แท้จริงของประเภทย่อยห้าประเภทข้างต้น หรือประเภทค่าที่ส่งคืนคือพารามิเตอร์ Type type
[สาเหตุที่ไม่มีวิธีการในอินเทอร์เฟซ Type]
ดังที่เห็นได้จากข้างต้น การเกิดขึ้นของ Type มีบทบาทในการปรับปรุงความสามารถในการขยายขนาดของโปรแกรมผ่านความหลากหลายเท่านั้น และไม่มีผลกระทบอื่นใด ดังนั้นจึงไม่มีวิธีการในซอร์สโค้ดของอินเทอร์เฟซ Type