Apa perbedaan antara <?> Dan <? extends Object> di Java Generics?

95

Saya telah melihat karakter pengganti yang digunakan sebelumnya untuk mengartikan objek apa pun - tetapi baru-baru ini saya melihat penggunaan:

<? extends Object>

Karena semua objek memperluas Object, apakah kedua penggunaan ini sama?

orbfish
sumber
2
Itu adalah hal yang sama. Lihat stackoverflow.com/questions/2274720/…
Dan
3
@Dan Jika Anda mencari "? Extends Object" dalam pertanyaan itu, Anda tidak akan menemukan apa pun. Saya membaca jawaban untuk melihat apakah saya dapat menyimpulkan sesuatu tetapi saya tidak berpikir ini dia. Secara khusus, ini tidak berbicara tentang obat generik.
orbfish
@Dan - Itu pertanyaan yang berbeda. Saya telah melihat pertanyaan ini sebelumnya dan saya ingat setidaknya satu penyebutan perbedaan yang halus. Biarkan saya melihat apakah saya dapat menemukannya ..
Paul Bellora
Ini juga bukan yang ini jika Anda menemukannya: stackoverflow.com/questions/678822/…
orbfish
1
Ini dia: kemungkinan duplikat wildcard Tak Terbatas di Java (Menampilkan jawaban yang salah oleh Kevin Bourrillion tidak kurang.)
Paul Bellora

Jawaban:

104

<?>dan <? extends Object>identik, seperti yang Anda harapkan.

Ada beberapa kasus dengan obat generik extends Objectyang sebenarnya tidak berlebihan. Misalnya, <T extends Object & Foo>akan menyebabkan Tmenjadi di Objectbawah penghapusan, sedangkan dengan <T extends Foo>itu akan menjadi di Foobawah penghapusan. (Ini dapat menjadi masalah jika Anda mencoba mempertahankan kompatibilitas dengan API pra-generik yang digunakan Object.)

Sumber: http://download.oracle.com/javase/tutorial/extra/generics/convert.html ; ini menjelaskan mengapa kelas JDK java.util.Collectionsmemiliki metode dengan tanda tangan ini:

public static <T extends Object & Comparable<? super T>> T max(
    Collection<? extends T> coll
)
ruakh
sumber
4
Saya tidak jelas bagaimana hubungannya dengan contoh tersebut? (karena tidak menggunakan <?> atau <? extends Object>)
orbfish
27
@orbfish: Hal ini terkait hanya dalam yang saya pikir Anda akan menemukan hal menarik, karena ini adalah contoh di mana extends Objectsebenarnya adalah bermakna. Jika saya salah, maka saya minta maaf. Mudah-mudahan akan menarik bagi orang lain yang mengetahui pertanyaan Anda, setidaknya.
ruakh
@ruakh - Lebih tertarik dengan karakter pengganti yang dibatasi daripada parameter jenis, tapi, setidaknya, Anda menjawab.
orbfish
1
Anda harus menyatakan itu di posting asli Anda. Dengan begitu, jawabannya bisa jadi lebih relevan bagi Anda.
liltitus 27
19

Meskipun <?>seharusnya menjadi jalan pintas <? extend object>, ada sedikit perbedaan di antara keduanya. <?>dapat diverifikasi sedangkan <? extend object>tidak. Alasan mereka melakukan ini adalah agar lebih mudah membedakan jenis yang dapat diubah. Apa pun yang terlihat seperti <? extends something>, <T>, <Integer>yang nonreifiable.

Misalnya, kode ini akan berfungsi

List aList = new ArrayList<>();
boolean instanceTest = aList instanceof List<?>;

tapi ini memberikan kesalahan

List aList = new ArrayList<>();
boolean instancetest = aList instanceof List<? extends Object>;

untuk info lebih lanjut baca generik Java dan koleksi oleh Maurice Naftalin

Renzhentaxi Baerde
sumber
Bagaimana List <?> Menjadi reifiable jika compiler akan menerjemahkannya ke List <Object> jadi informasi tentang apa tipenya? hilang?
Trismegistos
Apa yang saya yakini <?> Lebih dirancang untuk kompatibel ke belakang dengan API lama. membedakan dengan <Object> dan <? extends Object> yang merupakan kode post Java 5.
Dennis C
9

<?>adalah singkatan dari <? extends Object>. Anda dapat membaca tautan bersama di bawah ini untuk lebih jelasnya.


<?>

"?"menunjukkan jenis yang tidak diketahui, Ini dapat mewakili Jenis apa pun di dalam kode untuk. Gunakan wildcard ini jika Anda tidak yakin tentang Type.

ArrayList<?> unknownList = new ArrayList<Number>(); //can accept of type Number
unknownList = new ArrayList<Float>(); //Float is of type Number

Catatan: <?> berarti apa saja. Sehingga bisa menerima Type yang tidak diwarisi dari Objectclass.

<? extends Object>

<? extends Object>berarti Anda dapat mengirimkan Objek atau sub-kelas yang memperluas Objectkelas.

ArrayList<? extends Number> numberList = new ArrayList<Number>(); //Number of subclass
numberList = new ArrayList<Integer>(); //Integer extends Number
numberList = new ArrayList<Float>(); // Float extends Number 

masukkan deskripsi gambar di sini

T - digunakan untuk menunjukkan tipe
E - digunakan untuk menunjukkan elemen
K - kunci
V - nilai
N - untuk angka
Ref:

masukkan deskripsi gambar di sini

roottraveller.dll
sumber
"Jadi Ia dapat menerima Jenis yang tidak diwarisi dari kelas Objek", tetapi semua kelas Java diwarisi atau secara implisit diwarisi dari Objectkelas.
hackjutsu