Mengapa memilih wildcard daripada tipe diskriminator di Java API (Re: Java Efektif)

8

Di bagian generik Java Efektif Bloch (yang dengan mudahnya merupakan bab "gratis" yang tersedia untuk semua: http://java.sun.com/docs/books/effective/generics.pdf ), ia mengatakan:

Jika parameter tipe hanya muncul sekali dalam deklarasi metode, gantilah dengan wildcard.

(Lihat halaman 31-33 dari pdf itu)

Tanda tangan yang dimaksud adalah:

public static void swap(List<?> list, int i, int j)

vs.

public static void swap(List<E> list, int i, int j)

Dan kemudian mulai menggunakan fungsi "pembantu" privat statis dengan parameter tipe aktual untuk melakukan pekerjaan. Tanda tangan fungsi pembantu sama persis dengan opsi kedua.

Mengapa wildcard lebih disukai, karena Anda TIDAK perlu menggunakan wildcard untuk menyelesaikan pekerjaan? Saya memahami bahwa dalam hal ini karena dia memodifikasi Daftar dan Anda tidak dapat menambahkan ke koleksi dengan wildcard yang tidak terikat, jadi mengapa menggunakannya sama sekali?

Michael Campbell
sumber

Jawaban:

5

Mengapa wildcard lebih disukai

Saya percaya Josh menyatakannya dengan jelas:

Di API publik, [wildcard] lebih baik karena lebih sederhana.

Yaitu, untuk pengguna API. Kompleksitas ekstra kecil dalam implementasi tidak terlihat dari luar. Dan karena implementasinya ditulis hanya sekali, tetapi API dapat digunakan berkali-kali oleh banyak orang yang berbeda, menyederhanakan API dengan biaya membuat implementasi sedikit lebih kompleks masih merupakan kemenangan secara keseluruhan.

> mengapa menggunakannya sama sekali?

Maksudmu, mengapa lebih baik dari itu?

public static void swap(List list, int i, int j)

? Karena yang terakhir akan kehilangan semua obat generik, membiarkan kompiler mengabaikan semua pemeriksaan tipe generik, dan memungkinkan kita untuk menulis kode yang ceroboh. Saya pikir lebih baik menggunakan tanda tangan tipe generik walaupun ini bersifat umum, hanya untuk menjaga kebiasaan itu.

Pembaruan mencerminkan komentar di bawah ini

Anda lupa deklarasi parameter generik dari tanda tangan kedua, seharusnya itu benar

public static <E> void swap(List<E> list, int i, int j)

Artinya, <E>muncul dua kali, tanpa manfaat tambahan, vs <?>hanya muncul sekali di tanda tangan pertama. Inilah mengapa itu lebih sederhana.

Péter Török
sumber
1
Tidak, mengapa swap (Daftar <?>, ...) lebih baik daripada swap (Daftar <E>, ...). Saya gagal melihat mengapa itu lebih sederhana, dalam konteks apa pun.
Michael Campbell
1
Tidak terlalu melihat manfaatnya. Agar pengguna dapat menggunakan metode swap, panggilan ke versi public static <E> void swap (Daftar <E> daftar, int i, int j) atau public static void swap (Daftar <?> Daftar, int i, int j) akan lokk persis sama, yaitu swap (myList, 0, 1). Jadi apakah <E> muncul dua kali atau memiliki wildcard bukan masalah menurut saya. Mungkin saya melewatkan sesuatu?
Will
1
@Akan, sebelum menelepon, Anda (biasanya) membaca deklarasi API. Versi wildcard dari deklarasi ini (secara marginal) lebih sederhana untuk ditafsirkan oleh otak kita.
Péter Török
1
ok, jadi ini tentang penyederhanaan kecil ini. Terima kasih.
Will
2
Saya harus setuju dengan @Will, penyederhanaannya sangat kecil sehingga sulit untuk dilakukan.
Andres F.