สองตัวเลือกสำหรับการตรวจสอบประเภทรันไทม์ด้วย generics:
ตัวเลือกที่ 1 - ทำให้ตัวสร้างของคุณเสียหาย
สมมติว่าคุณกำลังลบล้าง indexOf (... ) และคุณต้องการตรวจสอบประเภทเพื่อประสิทธิภาพเท่านั้นเพื่อช่วยตัวเองในการทำซ้ำคอลเล็กชันทั้งหมด
สร้างตัวสร้างที่สกปรกเช่นนี้:
public MyCollection<T>(Class<T> t) {
this.t = t;
}
จากนั้นคุณสามารถใช้isAssignableFromเพื่อตรวจสอบประเภท
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
ทุกครั้งที่คุณสร้างอินสแตนซ์วัตถุของคุณคุณจะต้องทำซ้ำ:
new MyCollection<Apples>(Apples.class);
คุณอาจตัดสินใจว่ามันไม่คุ้มค่า ในการใช้งานArrayList.indexOf (... )พวกเขาไม่ได้ตรวจสอบว่าประเภทนั้นตรงกัน
ตัวเลือกที่ 2 - ปล่อยให้มันล้มเหลว
หากคุณต้องการใช้วิธีนามธรรมที่ต้องใช้ประเภทที่คุณไม่รู้จักสิ่งที่คุณต้องการจริงๆคือให้คอมไพเลอร์หยุดร้องไห้เกี่ยวกับอินสแตนซ์ของ หากคุณมีวิธีการดังนี้:
protected abstract void abstractMethod(T element);
คุณสามารถใช้มันได้ดังนี้:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
คุณกำลังส่งวัตถุเป็น T (ประเภททั่วไปของคุณ) เพียงเพื่อหลอกคอมไพเลอร์ นักแสดงของคุณไม่ได้ทำอะไรเลยในรันไทม์แต่คุณจะยังคงได้รับ ClassCastException เมื่อคุณพยายามส่งวัตถุผิดประเภทไปยังวิธีนามธรรมของคุณ
หมายเหตุ 1: หากคุณทำการแคสต์ที่ไม่ได้เลือกเพิ่มเติมในวิธีนามธรรมของคุณ ClassCastExceptions ของคุณจะถูกจับที่นี่ นั่นอาจจะดีหรือไม่ดีก็ลองคิดดู
หมายเหตุ 2: คุณจะได้รับการตรวจสอบ null ฟรีเมื่อคุณใช้ instanceof เนื่องจากคุณไม่สามารถใช้งานได้คุณอาจต้องตรวจสอบค่าว่างด้วยมือเปล่า
Class.isAssignableFrom
ผมไม่คิดว่าคุณต้องการ