Ini adalah contoh dunia nyata dari API pustaka pihak ketiga, tetapi disederhanakan.
Dikompilasi dengan Oracle JDK 8u72
Pertimbangkan dua metode ini:
<X extends CharSequence> X getCharSequence() {
return (X) "hello";
}
<X extends String> X getString() {
return (X) "hello";
}
Keduanya melaporkan peringatan "pemeran yang tidak dicentang" - Saya mengerti alasannya. Hal yang membingungkan saya adalah mengapa saya bisa menelepon
Integer x = getCharSequence();
dan mengkompilasi? Kompiler harus tahu bahwa Integer
tidak diimplementasikan CharSequence
. Panggilan ke
Integer y = getString();
memberikan kesalahan (seperti yang diharapkan)
incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
Dapatkah seseorang menjelaskan mengapa perilaku ini dianggap sah? Apa manfaatnya?
Klien tidak tahu bahwa panggilan ini tidak aman - kode klien dikompilasi tanpa peringatan. Mengapa kompilasi tidak akan memperingatkan tentang hal itu / mengeluarkan kesalahan?
Juga, apa bedanya dengan contoh ini:
<X extends CharSequence> void doCharSequence(List<X> l) {
}
List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles
List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error
Mencoba List<Integer>
memberikan kesalahan, seperti yang diharapkan:
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
Jika itu dilaporkan sebagai kesalahan, mengapa Integer x = getCharSequence();
tidak?
Integer x = getCharSequence();
akan dikompilasi, tetapi casting pada RHSInteger x = (Integer) getCharSequence();
gagal dikompilasi