ตามหนังสือ "Effective Java" ของ Joshua Bloch มีกฎเกี่ยวกับวิธีการ/เมื่อใช้ wildcards ที่มีขอบเขตในยาชื่อสามัญ กฎนี้คือ PECS (Producer-Extends, Comsumer-Super) เมื่อฉันศึกษาตัวอย่างต่อไปนี้:
Stack<Number> numberStack = new Stack<Number>();
Iterable<Integer> integers = ... ;
numberStack.pushAll(integers);
ฉันเข้าใจว่ากฎนี้เหมาะสมอย่างยิ่งในตัวอย่างนี้ ฉันต้องประกาศเมธอด pushAll
เป็นตัวอย่างต่อไปนี้:
// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
{
push(e);
}
}
แต่จะเกิดอะไรขึ้นถ้าฉันมีตัวอย่างต่อไปนี้
Stack<Integer> integerStack = new Stack<Integer>();
Iterable<Number> numbers = ... ;
integerStack.pushAll(numbers);
ฉันต้องประกาศ pushAll
ดังนี้:
public void pushAll(Iterable<? super E> src) {
for (E e : src)
{
push(e);
}
}
ตามกฎของ PECS การประกาศข้างต้นไม่ถูกต้อง แต่ฉันอยากได้ Stack
จาก Integer
s และส่งต่อไปยัง Stack
a Number
นี้ ทำไมไม่ทำล่ะ?
เหตุใดฉันจึงควรใช้คำหลัก extends
เสมอ ทำไมการใช้ super
ถึงผิด?
แน่นอนว่าสิ่งเดียวกันนี้หมายถึงมุมมองของผู้บริโภค เหตุใดผู้บริโภคจึงควรเป็น super
เสมอ
ปล.: หากต้องการให้เจาะจงยิ่งขึ้น คุณสามารถดูตัวอย่างข้างต้นได้ที่ส่วน "Item 28" ของหนังสือที่อ้างอิง