นี่คือตัวอย่างในโลกแห่งความเป็นจริงจาก API ไลบรารีบุคคลที่ 3 แต่ง่ายขึ้น
คอมไพล์ด้วย Oracle JDK 8u72
พิจารณาทั้งสองวิธี:
<X extends CharSequence> X getCharSequence() {
return (X) "hello";
}
<X extends String> X getString() {
return (X) "hello";
}
ทั้งคู่รายงานคำเตือน "นักแสดงที่ไม่ได้ตรวจสอบ" - ฉันเข้าใจว่าทำไม สิ่งที่ทำให้ฉันงุนงงคือทำไมฉันถึงโทรได้
Integer x = getCharSequence();
และมันรวบรวม? คอมไพเลอร์ควรจะรู้ว่าไม่ใช้Integer
CharSequence
การโทรไป
Integer y = getString();
ให้ข้อผิดพลาด (ตามที่คาดไว้)
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
มีคนอธิบายได้ไหมว่าเหตุใดพฤติกรรมนี้จึงถูกต้อง มันจะมีประโยชน์อย่างไร
ลูกค้าไม่ทราบว่าการโทรนี้ไม่ปลอดภัย - รหัสของลูกค้ารวบรวมโดยไม่มีการเตือน ทำไมคอมไพล์จึงไม่เตือนว่าเกิดข้อผิดพลาด?
นอกจากนี้มันแตกต่างจากตัวอย่างนี้อย่างไร:
<X extends CharSequence> void doCharSequence(List<X> l) {
}
List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles
List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error
การพยายามส่งผ่านList<Integer>
มีข้อผิดพลาดตามที่คาดไว้:
method doCharSequence in class generic.GenericTest cannot be applied to given types; required: java.util.List<X> found: java.util.List<java.lang.Integer> reason: inference variable X has incompatible bounds equality constraints: java.lang.Integer upper bounds: java.lang.CharSequence
หากรายงานว่าเป็นข้อผิดพลาดทำไมถึงInteger x = getCharSequence();
ไม่ใช่
Integer x = getCharSequence();
จะรวบรวม แต่การคัดเลือกนักแสดงที่ RHSInteger x = (Integer) getCharSequence();
ไม่สามารถรวบรวมได้