Saya tampaknya memiliki kesalahpahaman tentang perbedaan antara <Foo>dan <? extends Foo>. Dari pemahaman saya, jika kita punya
ArrayList<Foo> foos = new ArrayList<>();
Ini menunjukkan bahwa objek tipe Foodapat ditambahkan ke daftar array ini. Karena subclass dari Foojuga bertipe Foo, mereka juga dapat ditambahkan tanpa kesalahan, seperti yang diilustrasikan oleh
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
mana Bar extends Foo.
Sekarang, katakanlah saya telah mendefinisikan foossebagai
ArrayList<? extends Foo> foos = new ArrayList<>();
Pemahaman saya saat ini adalah bahwa ini diungkapkan some unknown type that extends Foo. Saya menganggap ini berarti bahwa objek apa pun yang merupakan subkelas Foodapat ditambahkan ke daftar ini; artinya tidak ada perbedaan antara ArrayList<Foo>dan ArrayList<? extends Foo>.
Untuk menguji ini, saya mencoba menulis kode berikut
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
tetapi diminta dengan kesalahan kompilasi berikut
no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)
no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)
Berdasarkan pemahaman saya saat ini, saya dapat melihat mengapa saya mungkin tidak dapat menambahkan a Fooke daftar <? extends Foo>, karena itu bukan subkelas dari dirinya sendiri; tapi saya ingin tahu mengapa saya tidak bisa menambahkan Barke daftar.
Di mana lubang pemahaman saya?
<? extends Foo>adalah kelas spesifik dan tidak dikenal yang diperluas Foo. Operasi dengan kelas ini hanya sah jika akan sah untuk setiap subkelas dari Foo.