Ini adalah potongan kecil kode yang diambil dari beberapa contoh yang menyertai Stanford Parser. Saya telah mengembangkan di Jawa selama sekitar 4 tahun, tetapi tidak pernah memiliki pemahaman yang sangat kuat tentang apa yang seharusnya ditunjukkan oleh gaya kode ini.
List<? extends HasWord> wordList = toke.tokenize();
Saya tidak khawatir tentang detail kode. Yang saya bingung adalah apa yang seharusnya disampaikan oleh ekspresi generik, dalam bahasa Inggris.
Adakah yang bisa menjelaskan hal ini kepada saya?
Jawaban:
berarti "Kelas / antarmuka yang memanjang
HasWord
." Dengan kata lain,HasWord
itu sendiri atau salah satu dari anak-anaknya ... pada dasarnya apa pun yang sesuai denganinstanceof HasWord
plusnull
.Dalam istilah yang lebih teknis,
? extends HasWord
adalah wildcard terbatas, tercakup dalam Item 31 dari Java Edisi 3 Efektif , mulai dari halaman 139. Bab yang sama dari Edisi 2 tersedia online dalam bentuk PDF ; bagian pada wildcard terbatas adalah Item 28 mulai dari halaman 134.Pembaruan: Tautan PDF telah diperbarui sejak Oracle menghapusnya beberapa waktu lalu. Sekarang menunjuk ke salinan yang dipandu oleh Sekolah Teknik Elektronika dan Ilmu Komputer Queen Mary University London.
Pembaruan 2: Mari kita sedikit lebih detail tentang mengapa Anda ingin menggunakan wildcard.
Jika Anda mendeklarasikan metode yang tanda tangannya ingin Anda lewati
List<HasWord>
, maka satu-satunya hal yang dapat Anda lewati adalah aList<HasWord>
.Namun, jika tanda tangan itu
List<? extends HasWord>
maka Anda bisa lewatList<ChildOfHasWord>
.Perhatikan bahwa ada perbedaan tipis antara
List<? extends HasWord>
danList<? super HasWord>
. Seperti yang dikatakan Joshua Bloch: PECS = produsen-meluas, konsumen-super.Apa artinya ini adalah bahwa jika Anda meneruskan koleksi yang metode Anda tarik data dari (yaitu koleksi menghasilkan elemen untuk metode Anda untuk menggunakan), Anda harus menggunakan
extends
. Jika Anda meneruskan koleksi yang ditambahkan metode Anda ke data (mis. Koleksi tersebut menggunakan elemen yang dibuat metode Anda), itu harus digunakansuper
.Ini mungkin terdengar membingungkan. Namun, Anda dapat melihatnya di
List
'ssort
perintah (yang hanya jalan pintas untuk versi dua-arg dari Collections.sort). Alih-alih mengambilComparator<T>
, itu sebenarnya membutuhkanComparator<? super T>
. Dalam hal ini, Pembanding mengkonsumsi elemen-elemenList
untuk menyusun ulang Daftar itu sendiri.sumber
List<HasWord>
persis seperti yang Anda gambarkan: Daftar yang berisi objek apa punx
yangx instanceof HasWord
mengembalikan true, dannull
. Anda tidak perlu wildcard untuk ini. Wildcard berarti bahwa itu sebenarnya bisa menjadi daftar tipe lain juga, asalkan tipe ini adalah subtipe dariHasWord
. (Maaf atas komentar terakhir.)Tanda tanya adalah penanda untuk 'jenis apa pun'.
?
sendiri artinyasedangkan contoh Anda di atas berarti
sumber
public Set<Class<?>> getClasses()
artinya? Apa bedanya denganSet<Class>
? Saya sedang melihatjavax.ws.rs.core.Application
.List<? extends HasWord>
menerima setiap kelas konkret yang memperluas HasWord. Jika Anda memiliki kelas berikut ......
wordList
HANYA bisa berisi daftar As atau B atau campuran keduanya karena kedua kelas memperpanjang induk yang sama ataunull
(yang gagal contoh pemeriksaanHasWorld
).sumber
List<? extends Collection<String>> list = new ArrayList<List<String>>();
.List<HasWord>
melakukan dengan baik untuk ini. Intinya di sini adalah bahwa variabel ini dapat berisiList<A>
atauList<B>
juga aList<HasWord>
.Mungkin contoh "dunia nyata" yang dibuat-buat akan membantu.
Di tempat kerja saya, kami memiliki tempat sampah yang berbeda rasa. Semua tempat sampah mengandung sampah, tetapi beberapa tempat sampah adalah spesialis dan tidak mengambil semua jenis sampah. Jadi kita punya
Bin<CupRubbish>
danBin<RecylcableRubbish>
. Sistem tipe perlu memastikan saya tidak dapat memasukkan sayaHalfEatenSandwichRubbish
ke salah satu dari jenis ini, tetapi dapat masuk ke tempat sampah umumBin<Rubbish>
. Jika saya ingin berbicara tentangBin
dariRubbish
yang mungkin khusus jadi saya tidak bisa dimasukkan ke dalam sampah tidak sesuai, maka itu akan menjadiBin<? extends Rubbish>
.(Catatan:
? extends
tidak berarti hanya baca. Misalnya, saya dapat dengan tindakan pencegahan yang tepat mengeluarkan sepotong sampah dari tempat khusus yang tidak diketahui dan kemudian meletakkannya kembali di tempat yang berbeda.)Tidak yakin berapa banyak yang membantu. Pointer-to-pointer di hadapan polimorfisme tidak sepenuhnya jelas.
sumber
Dalam Bahasa Inggris:
Secara umum
?
dalam generik berarti kelas apa saja. Danextends SomeClass
menentukan bahwa objek itu harus diperluasSomeClass
(atau kelas itu).sumber
Tanda tanya digunakan untuk mendefinisikan wildcard . Lihat dokumentasi Oracle tentang mereka: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
sumber