ฉันกำลังอ่านเกี่ยวกับวิธีการทั่วไปจากOracleDocGenericMethod ฉันค่อนข้างสับสนเกี่ยวกับการเปรียบเทียบเมื่อมีการบอกว่าเมื่อใดควรใช้ไวด์การ์ดและเมื่อใดควรใช้วิธีการทั่วไป อ้างจากเอกสาร
interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); }
เราสามารถใช้วิธีการทั่วไปได้ที่นี่แทน:
interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); // Hey, type variables can have bounds too! }
[…] สิ่งนี้บอกเราว่าประเภทอาร์กิวเมนต์ถูกใช้สำหรับความหลากหลาย; ผลกระทบเพียงอย่างเดียวคืออนุญาตให้ใช้ประเภทอาร์กิวเมนต์จริงที่หลากหลายในไซต์การร้องขอที่แตกต่างกัน หากเป็นเช่นนั้นควรใช้สัญลักษณ์แทน สัญลักษณ์แทนได้รับการออกแบบมาเพื่อรองรับการพิมพ์ย่อยที่ยืดหยุ่นซึ่งเป็นสิ่งที่เราพยายามแสดงที่นี่
เราไม่คิดว่าไวด์การ์ด(Collection<? extends E> c);
ก็สนับสนุนความหลากหลายของรูปแบบเช่นกัน? แล้วทำไมการใช้วิธีการทั่วไปจึงถือว่าไม่ดีในเรื่องนี้?
กล่าวต่อไปว่า
วิธีการทั่วไปอนุญาตให้ใช้พารามิเตอร์ชนิดเพื่อแสดงการอ้างอิงระหว่างประเภทของอาร์กิวเมนต์หนึ่งหรือหลายอาร์กิวเมนต์สำหรับวิธีการและ / หรือประเภทการส่งคืน หากไม่มีการพึ่งพาดังกล่าวไม่ควรใช้วิธีการทั่วไป
สิ่งนี้หมายความว่า?
พวกเขาได้นำเสนอตัวอย่าง
class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... }
[ ... ]
เราสามารถเขียนลายเซ็นสำหรับวิธีนี้ได้อีกวิธีหนึ่งโดยไม่ต้องใช้สัญลักษณ์แทนเลย:
class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... }
เอกสารไม่สนับสนุนการประกาศครั้งที่สองและส่งเสริมการใช้ไวยากรณ์แรก? การประกาศครั้งแรกและครั้งที่สองแตกต่างกันอย่างไร ทั้งคู่ดูเหมือนจะทำสิ่งเดียวกัน?
มีใครช่วยให้แสงสว่างในพื้นที่นี้
?
เลย คุณสามารถเขียนใหม่เป็น `public static <T1 ขยาย Number, T2 ขยาย Number> สำเนาเป็นโมฆะ (List <T1> dest, List <T2> src) และในกรณีนี้จะเห็นได้ชัดว่าเกิดอะไรขึ้น