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 Foo
dapat ditambahkan ke daftar array ini. Karena subclass dari Foo
juga 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 foos
sebagai
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 Foo
dapat 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 Foo
ke daftar <? extends Foo>
, karena itu bukan subkelas dari dirinya sendiri; tapi saya ingin tahu mengapa saya tidak bisa menambahkan Bar
ke daftar.
Di mana lubang pemahaman saya?
<? extends Foo>
adalah kelas spesifik dan tidak dikenal yang diperluasFoo
. Operasi dengan kelas ini hanya sah jika akan sah untuk setiap subkelas dariFoo
.Jawaban:
Seperti yang Anda temukan sendiri,
ArrayList
pernyataanArrayList<? extends Foo> subFoos = new ArrayList<>();
tidak akan sangat berguna.Untuk melihat manfaat dari
<? extends T>
pertimbangan ini:yang nantinya bisa digunakan sebagai berikut:
atau sebagai berikut:
perhatikan bahwa tidak satu pun di atas akan berfungsi jika
collect
metode telah dinyatakan sebagai berikut:sumber