Makalah ini menganalisis perbedaan antara JDK1.4, JDK1.5 dan JDK1.6 dalam pemrograman Java dalam kombinasi dengan contoh. Bagikan untuk referensi Anda, sebagai berikut:
Sederhananya: Ada dua perbedaan terbesar antara 1,4 dan 1,5. Salah satunya adalah bahwa 1,5 memiliki obat generik, dan yang lainnya 1.5 dapat secara otomatis merangkum tipe data yang dienkapsulasi dari delapan tipe data dasar. Artinya, Integer A = 4 tidak diperbolehkan. Tidak ada banyak perbedaan antara 1,5 dan 1,6. 1.6 Saya pikir sebagian besar perubahan adalah GUI, yang menyediakan banyak manajemen tata letak yang nyaman dan ekstensi.
Selama periode ini, saya bergabung dengan perusahaan e-government dan menggunakan WebLogic8. Lalu mari kita gunakan jdk1.4. Eclipse mengubah versi JDK. Namun, proyek sebelumnya pada dasarnya menjadi populer.
★ Fitur baru JDK1.5:
1. Generik
2 pengepakan/unboxing otomatis
3 untuk setiap
4 impor statis
5 parameter panjang variabel
1. Generik (hindari menjalankan kesalahan yang mungkin disebabkan oleh casting tipe)
Misalnya:
Daftar ArrayList = ArrayList baru (); list.add (bilangan bulat baru (3)); list.add (bilangan bulat baru (4)); int i = ((integer) (list.get (0))). parseInt ();
Sangat merepotkan
ArrayList <Integer> Daftar = ArrayList baru <Integer> (); list.add (bilangan bulat baru (3)); list.add (bilangan bulat baru (4)); int i = list.get (0) .parseint ();
2 pengepakan/unboxing otomatis
Kalimat terakhir dari contoh di atas dapat diubah menjadi:
Salinan kode adalah sebagai berikut: int i = list.get (0);
Karena jenis asli dan kelas pembungkus yang sesuai tidak perlu dikonversi secara eksplisit
3 untuk setiap
Peningkatan loop
int a [] = {......}; // inisialisasi untuk (int i: a) {......}Jangan gunakan i = 0; i <a.length; i ++ sebelumnya
4 impor statis
Java.math yang sebelumnya disetel
Salinan kode adalah sebagai berikut: Math.sqrt ();
Sekarang statis impor java.lang.math.sqrt;
sqrt ();
Setara dengan memiliki metode ini di kelas Anda sendiri
5 parameter panjang variabel
int sum (int ... intlist) {int sum; jumlah = 0; untuk (int i = 0; i <intlist.length; i ++) {sum+= intlist [i]; } return sum;}Ada parameter, perlakukan itu sebagai array
★ Fitur baru JDK6.0
Ditingkatkan untuk enumerasi anotasi pernyataan loop dari parameter variadik metode statis "tersembunyi" (varArg)
Wildcards and Covariance Return ditingkatkan untuk pernyataan loop
Untuk mengulangi set dan array, yang ditingkatkan untuk loop memberikan sintaks yang sederhana dan kompatibel. Ada dua poin yang layak disebut:
1. Dalam satu loop, ekspresi inisialisasi dihitung hanya sekali. ekspresi int
Tidak ditingkatkan untuk:
int sum = 0; Integer [] angka = computeNumbers (); untuk (int i = 0; i <number.length; i ++) jumlah+= angka [i];
Ditingkatkan untuk:
int sum = 0; untuk (nomor int: computEnumbers ()) sum += angka;
keterbatasan
Iterator atau subskrip tidak dapat diakses selama ditingkatkan untuk iterasi loop
Silakan lihat contoh berikut:
untuk (int i = 0; i <number.length; i ++) {if (i! = 0) system.out.print (","); System.out.print (angka [i]);}Berikut adalah contoh lain:
untuk (iterator <Integer> it = n.iterator (); it.hasnext ();) if (it.next () <0) it.remove ();
Komentar
Pemrosesan komentar adalah topik besar. Karena artikel ini hanya berfokus pada fitur bahasa inti, kami tidak bermaksud untuk mencakup semua bentuk dan jebakan yang mungkin. Kami akan membahas anotasi bawaan (SuppressWarnings, sudah usang dan override) dan keterbatasan pemrosesan anotasi umum.
Tekan peringatan
Komentar ini mematikan peringatan kompiler di tingkat kelas atau metode. Kadang-kadang Anda tahu lebih jelas daripada kompiler bahwa kode harus menggunakan metode yang ditolak atau melakukan beberapa tindakan yang tidak dapat secara statis menentukan apakah jenis-aman-aman-aman, dan menggunakan:
@SuppressWarnings ("Deprecation") public static void selfDestruct () {thread.currentThread (). Stop ();}Ini mungkin hal yang paling berguna tentang anotasi bawaan. Sayangnya, Javac untuk 1.5.0_04 tidak mendukungnya. Tapi 1.6 mendukungnya, dan Sun bekerja untuk porting ke belakang menjadi 1.5.
Anotasi ini didukung dalam Eclipse 3.1, dan IDE lainnya juga dapat mendukungnya. Ini memungkinkan Anda untuk sepenuhnya membebaskan kode dari peringatan. Jika ada peringatan pada waktu kompilasi, Anda dapat yakin bahwa Anda baru saja menambahkannya - untuk membantu melihat kode yang mungkin tidak aman. Dengan penambahan obat generik, akan lebih berguna untuk digunakan.
Tercerahkan
Sayangnya, usang tidak terlalu berguna. Awalnya dimaksudkan untuk menggantikan tag Javadoc @Deprecated, tetapi karena tidak berisi bidang apa pun, tidak ada cara untuk menyarankan pengguna kelas atau metode yang sudah usang yang harus digunakan sebagai pengganti. paling
Kedua penggunaan membutuhkan tag Javadoc dan anotasi ini.
Mengesampingkan
Override mengatakan bahwa metode yang dianotasi harus mengganti metode dengan tanda tangan yang sama di superclass:
@Overridepublic int hashCode () {...}Melihat contoh di atas, jika "C" tidak dikapitalisasi dalam kode hash, tidak akan ada kesalahan pada waktu kompilasi, tetapi metode ini tidak akan disebut seperti yang diharapkan saat runtime. Dengan menambahkan tag override, kompiler akan meminta jika benar -benar melakukan penulisan ulang.
Ini juga membantu dalam situasi di mana superclass berubah. Jika parameter baru ditambahkan ke metode ini, dan metode itu sendiri diganti namanya, subkelas tiba -tiba tidak akan dikompilasi karena tidak lagi menulis ulang apa pun dari superclass.
Catatan lainnya
Komentar sangat berguna dalam skenario lain. Ketika tidak memodifikasi perilaku secara langsung tetapi meningkatkan perilaku, terutama ketika menambahkan kode boilerplate, anotasi bekerja dengan sangat baik dalam kerangka kerja seperti EJB dan layanan web.
Komentar tidak dapat digunakan sebagai preprosesor. Desain Sun secara khusus mencegah modifikasi bytecode kelas sepenuhnya karena komentar. Ini memungkinkan Anda untuk memahami hasil bahasa dengan benar, dan alat-alat seperti IDE juga dapat melakukan analisis dan refactoring kode yang mendalam.
Komentar itu bukan peluru perak. Ketika saya pertama kali menemui, orang mencoba mencoba berbagai teknik. Silakan lihat saran berikut yang diperoleh dari orang lain:
kelas publik foo {@propertyprivate int bar;}Idenya adalah untuk secara otomatis membuat metode pengambil dan setter untuk bilah lapangan pribadi. Sayangnya, ada dua kegagalan dalam ide ini: 1) tidak berhasil, dan 2) membuat kode sulit dibaca dan diproses. Tidak mungkin untuk diimplementasikan, karena seperti yang disebutkan sebelumnya, Sun secara khusus mencegah modifikasi kelas dengan komentar.
Bahkan jika memungkinkan, itu bukan ide yang baik karena membuat kode dapat dibaca dengan buruk. Pertama kali Anda melihat kode ini, Anda tidak akan tahu bahwa komentar membuat metode. Juga, jika Anda perlu melakukan beberapa operasi di dalam metode ini di masa depan, komentar tidak berguna. Singkatnya, jangan mencoba melakukan hal -hal yang dapat dilakukan kode biasa dengan komentar.
menghitung
ENUM sangat mirip dengan deklarasi int final statis publik, yang telah digunakan sebagai nilai enum selama bertahun -tahun. Peningkatan terbesar dan paling jelas untuk int adalah jenis keamanan - Anda tidak dapat secara keliru mengganti jenis lain dengan satu jenis enumerasi, yang berbeda dari int, dan semua int adalah sama untuk kompiler. Dengan sangat sedikit pengecualian, semua struktur int gaya enum biasanya harus diganti dengan instance enum.
Pencacahan menyediakan beberapa fitur tambahan. Dua kelas praktis enummap dan enumset adalah implementasi set standar dioptimalkan untuk enumerasi. Jika Anda tahu bahwa koleksi hanya berisi jenis enum, Anda harus menggunakan koleksi khusus ini alih -alih hashmap atau hashset.
Dalam kebanyakan kasus, Anda dapat menggunakan ENUM untuk mengganti semua INT final statis publik dalam kode. Mereka sebanding dan dapat diimpor secara statis, sehingga referensi untuk mereka tampaknya setara, bahkan untuk kelas dalam (atau tipe enum dalam). Perhatikan bahwa ketika membandingkan jenis enum, instruksi yang menyatakannya menunjukkan nilai -nilai berurutan mereka.
Metode statis "tersembunyi"
Dua metode statis muncul dalam semua deklarasi tipe enum. Karena mereka adalah metode statis pada subkelas enum, bukan metode enum itu sendiri, mereka tidak muncul di javadoc dari java.lang.enum.
Yang pertama adalah nilai (), yang mengembalikan array dari semua nilai yang mungkin dari jenis enumerasi.
Yang kedua adalah nilai (), yang mengembalikan jenis enum untuk string yang disediakan, yang harus persis sesuai dengan deklarasi kode sumber.
metode
Salah satu aspek favorit kami tentang jenis enum adalah bahwa ia dapat memiliki metode. Di masa lalu Anda mungkin harus menulis beberapa kode untuk mengonversi int final statis publik dan mengonversinya dari jenis database ke URL JDBC. Sekarang, jenis enum itu sendiri dapat dibuat dengan lengkap
Metode untuk memanipulasi kode. Berikut adalah contoh, termasuk metode abstrak tipe ENUM DatabaseType dan implementasi yang disediakan dalam setiap instance enum:
PUBLIK ENUM DATABASETYPE {oracle {public String getjdbCurl () {...}}, mysql {public string getjdbcurl () {...}}; string abstrak publik getjdbcurl ();}Sekarang jenis enum dapat secara langsung memberikan metode praktisnya. Misalnya:
DataBasetype dBType = ...; String jdbcurl = dBType.getjdbcurl ();
Untuk mendapatkan URL, Anda harus tahu terlebih dahulu di mana metode utilitas berada.
Vararg
Menggunakan parameter yang dapat berubah dengan benar tidak membersihkan beberapa kode sampah. Contoh tipikal adalah metode log dengan jumlah variabel parameter string:
Log.log (kode string) log.log (kode string, string arg) log.log (kode string, string arg1, string arg2) log.log (kode string, string [] args)
Saat membahas parameter variabel, menarik bahwa jika Anda mengganti empat contoh pertama dengan parameter variabel baru, itu akan kompatibel:
Salin kode sebagai berikut: log.log (kode string, string ... args)
Semua parameter yang dapat berubah kompatibel dengan sumber - yaitu, jika semua program panggilan dari metode log () dikompilasi ulang, keempat metode dapat diganti secara langsung. Namun, jika kompatibilitas biner mundur diperlukan, maka tiga metode pertama perlu ditinggalkan. Hanya metode terakhir dengan parameter array string yang setara dengan versi variadik, sehingga dapat diganti dengan versi variadik.
Ketik Cast
Jika Anda ingin penelepon mengetahui jenis parameter mana yang harus digunakan, Anda harus menghindari tipe casting dengan parameter yang dapat berubah. Melihat contoh berikut, harapan pertama adalah string, dan harapan kedua adalah pengecualian:
Log.log (objek ... objek) {string message = (string) objek [0]; if (objects.length> 1) {exception e = (pengecualian) objek [1]; // Lakukan sesuatu dengan pengecualian}} Tanda tangan metode harus sebagai berikut, dan parameter yang dapat berubah yang sesuai dinyatakan menggunakan string dan pengecualian masing -masing:
Salinan kode adalah sebagai berikut: log.log (pesan string, pengecualian e, objek ... objek) {...}
Jangan gunakan parameter variabel untuk menghancurkan sistem tipe. Ini hanya dapat digunakan saat diketik dengan kuat. Untuk aturan ini, printStream.printf () adalah pengecualian yang menarik: ia memberikan informasi jenis sebagai argumen pertama sehingga jenis -jenis tersebut dapat diterima nanti.
Kembalinya kovarians
Penggunaan dasar pengembalian kovarian adalah untuk menghindari jenis casting ketika tipe pengembalian implementasi diketahui lebih spesifik daripada API. Dalam contoh berikut, ada antarmuka kebun binatang yang mengembalikan objek hewan. Implementasi kami mengembalikan objek AnimalImpl, tetapi sebelum JDK 1.5, itu harus dinyatakan mengembalikan objek hewan. :
Zoo Antarmuka Publik {hewan publik getanimal ();} kelas publik ZooImpl mengimplementasikan zoo {hewan publik getanimal () {return new animalImpl ();}}Penggunaan pengembalian kovarian menggantikan tiga anti-pola:
Akses Langsung Bidang. Untuk menghindari batasan API, beberapa implementasi mengekspos subclass langsung ke bidang:
Salin kode sebagai berikut: ZooImpl._animal
Formulir lain adalah melakukan konversi turun dalam program panggilan, mengetahui bahwa implementasinya sebenarnya adalah subkelas tertentu:
Salinan kode adalah sebagai berikut: ((animalImpl) zooImpl.getAnimal ()). Imprmethod ();
Bentuk terakhir yang saya lihat adalah metode konkret yang digunakan untuk menghindari masalah yang disebabkan oleh tanda tangan yang sama sekali berbeda:
Salinan kode adalah sebagai berikut: zooImpl._getanimal ();
Ketiga mode ini memiliki masalah dan keterbatasan mereka. Entah itu tidak cukup rapi atau memaparkan detail implementasi yang tidak perlu.
Kovarians
Mode pengembalian kovarian lebih bersih, lebih aman dan mudah dipelihara, dan tidak memerlukan jenis casting atau metode atau bidang tertentu:
Public AnimalImpl getanimal () {return new baru animalImpl (); } Gunakan Hasil:
Salinan kode adalah sebagai berikut: zooImpl.getAnimal (). Imprmethod ();
Menggunakan obat generik
Kami akan belajar tentang obat generik dari dua perspektif: menggunakan obat generik dan membangun obat generik. Kami tidak membahas penggunaan daftar, set, dan peta yang jelas. Cukuplah untuk mengetahui bahwa koleksi generik kuat dan harus sering digunakan.
Kami akan membahas penggunaan metode generik dan metode kompiler untuk menyimpulkan jenis. Biasanya tidak satu pun dari ini akan salah, tetapi ketika ada yang salah, pesan kesalahan bisa sangat membingungkan, jadi Anda perlu tahu cara memperbaiki masalah ini.
Metode generik
Selain jenis generik, Java 5 juga memperkenalkan metode generik. Dalam contoh ini dari java.util.collections, daftar elemen tunggal dibangun. Jenis elemen dari daftar baru disimpulkan berdasarkan jenis objek yang dilewati dalam metode:
Salin kode sebagai berikut: statis <T> Daftar <T> collections.singletonlist (t o)
Contoh Penggunaan:
Daftar Publik <Integer> getListofone () {return collections.singletonList (1);}Dalam penggunaan contoh, kami lulus di int. Jadi tipe pengembalian metode ini adalah daftar <Integer>. Kompiler menyimpulkan T ke integer. Ini berbeda dari tipe generik, karena Anda biasanya tidak perlu menentukan parameter tipe secara eksplisit.
Ini juga menunjukkan interaksi antara autoboxing dan generik. Parameter tipe harus berupa jenis referensi: itulah sebabnya kami mendapatkan daftar <Integer> alih -alih Daftar <TTT>.
Metode generik tanpa parameter
Metode emptylist () diperkenalkan dengan obat generik sebagai permutasi jenis-aman dari bidang kosong_list di java.util.collections:
Salin kode sebagai berikut: statis <T> Daftar <T> collections.emptylist ()
Contoh Penggunaan:
Daftar Publik <Integer> getNointegers () {return collections.emptylist ();}Berbeda dengan contoh sebelumnya, metode ini tidak memiliki parameter, jadi bagaimana kompiler menyimpulkan jenis t? Pada dasarnya, ia akan mencoba menggunakan parameter sekali. Jika tidak berhasil, ia mencoba menggunakan jenis pengembalian atau penugasan lagi. Dalam contoh ini, pengembalian adalah daftar <integer>, jadi t disimpulkan sebagai integer.
Apa yang terjadi jika metode generik dipanggil di luar pernyataan pengembalian atau pernyataan penugasan? Maka kompiler tidak akan dapat melakukan transfer kedua inferensi tipe. Dalam contoh berikut, emptylist () dipanggil dari dalam operator bersyarat:
Daftar Publik <Integer> getNointegers () {return x? Collections.emptylist (): null;} Karena kompiler tidak dapat melihat konteks pengembalian dan tidak dapat menyimpulkan, ia meninggalkan dan mengambil keberatan. Anda akan melihat pesan kesalahan seperti: "Tidak dapat mengonversi Daftar <POMPENT> ke daftar <Integer>."
Untuk memperbaiki kesalahan ini, ketik parameter harus diteruskan secara eksplisit ke panggilan metode. Dengan cara ini, kompiler tidak akan mencoba menyimpulkan parameter tipe dan bisa mendapatkan hasil yang benar:
Salinan kode adalah sebagai berikut: return x? Koleksi. <Integer> emptylist (): null;
Tempat lain di mana ini sering terjadi dalam panggilan metode. Jika suatu metode mengambil parameter daftar <string> dan perlu memanggil empa yang dilewati () untuk parameter itu, maka sintaks ini juga diperlukan.
Di luar koleksi
Berikut adalah tiga contoh jenis generik, yang bukan koleksi, tetapi menggunakan obat generik dengan cara yang baru. Ketiga contoh berasal dari perpustakaan Java standar:
Salin kode sebagai berikut: Kelas <T>
Kelas diparameterisasi pada jenis kelas. Ini memungkinkan untuk membangun newinstance tanpa casting tipe.
Salin kode sebagai berikut: sebanding <T>
Sebanding diparameterisasi oleh tipe perbandingan aktual. Ini memberikan pengetikan yang lebih kuat jika dibandingkan dengan () panggilan. Misalnya, string mengimplementasikan <string> yang sebanding. Memanggil compareto () pada apa pun selain string akan gagal pada waktu kompilasi.
Salin kode sebagai berikut: enum <e memperluas enum <E>>
Enum diparameterisasi berdasarkan jenis enum. Jenis ENUM bernama warna akan memperpanjang ENUM <nol color>. Metode getDeclaringClass () mengembalikan objek kelas tipe enumerasi, dalam contoh ini, objek warna. Ini berbeda dari getClass (), yang dapat mengembalikan kelas tanpa nama.
Wildcard
Bagian obat generik yang paling kompleks adalah pemahaman karakter wildcard. Kami akan membahas tiga jenis wildcard dan penggunaannya.
Pertama mari kita mengerti bagaimana array bekerja. Anda dapat menetapkan nilai dari bilangan bulat [] ke angka []. Jika Anda mencoba menulis float to number [], itu dapat dikompilasi, tetapi akan gagal saat runtime dan arrayStoreException muncul:
Integer [] ia = integer baru [5]; angka [] na = ia; na [0] = 0,5; // mengkompilasi, tetapi gagal saat runtime
Jika Anda mencoba mengubah contoh secara langsung menjadi generik, itu akan gagal pada waktu kompilasi karena tugas tidak diizinkan:
Daftar <Integer> ilist = ArrayList baru <Integer> (); Daftar <number> nlist = ilist; // tidak diizinkannlist.add (0,5);
Jika Anda menggunakan obat generik, Anda tidak akan menemukan runtime ClassCastException selama kode tidak muncul saat menyusun.
Batas Wildcard atas
Yang kami inginkan adalah daftar jenis elemen yang tepat yang tidak diketahui, yang berbeda dari array.
Daftar <number> adalah daftar yang jenis elemennya adalah nomor tipe spesifik.
Daftar <? Extends Number> adalah daftar jenis elemen yang tepat yang tidak diketahui. Itu adalah angka atau subtipe.
Batas atas
Jika kami memperbarui contoh awal dan menetapkan nilai untuk daftar <? memperpanjang nomor>, maka tugas akan berhasil sekarang:
Daftar <Integer> ilist = new ArrayList <Integer> (); Daftar <? memperluas angka> nlist = ilist; angka n = nlist.get (0); nlist.add (0.5); // tidak diizinkan
Kita bisa mendapatkan nomor dari daftar karena kita dapat menetapkannya ke nomor terlepas dari jenis elemen yang tepat dari daftar (float, integer, atau nomor).
Kami masih tidak dapat memasukkan tipe titik mengambang ke dalam daftar. Ini akan gagal pada waktu kompilasi karena kami tidak dapat membuktikan bahwa ini aman. Jika kita ingin menambahkan jenis titik mengambang ke daftar, itu akan merusak keamanan tipe awal ilist - itu hanya menyimpan integer.
Wildcard memberi kita kekuatan yang lebih ekspresif daripada array.
Mengapa menggunakan wildcard
Dalam contoh berikut, wildcard digunakan untuk menyembunyikan informasi jenis dari pengguna API. Secara internal, set disimpan sebagai CustomerImpl. Pengguna API hanya tahu bahwa mereka mendapatkan satu set dari mana mereka dapat membaca pelanggan.
Wildcard diperlukan di sini karena tidak mungkin untuk menetapkan nilai untuk mengatur <sust customer> dari set <sust customerMl>:
Public Class CustomerFactory {Private Set <sust customerImpl> _customers; public set <? Extends Customer> getCustomers () {return _customers;}}Wildcard dan kembalinya kovarian
Penggunaan umum lain dari karakter wildcard adalah menggunakannya dengan kembalinya kovarian. Aturan yang sama dengan penugasan dapat diterapkan pada pengembalian kovarian. Jika Anda ingin mengembalikan tipe generik yang lebih spesifik dalam metode yang ditulis ulang, metode yang dinyatakan harus menggunakan wildcard:
Antarmuka Publik NumberGenerator {Daftar Publik <? Extends Number> Generate ();} Kelas Publik FibonAccigenerator Memperluas NumberGenerator {Daftar Publik <Integer> Generate () {...}}Jika Anda ingin menggunakan array, antarmuka dapat mengembalikan nomor [], sementara implementasi dapat mengembalikan integer [].
Batas bawah
Apa yang kita bicarakan terutama tentang wildcard batas atas. Ada juga wildcard batas bawah. Daftar <? Super Number> adalah daftar "tipe elemen" yang tepat tidak diketahui, tetapi mungkin mnumber, atau supertype angka. Jadi mungkin daftar <number> atau daftar <POBPENT>.
Wildcard yang terbatas rendah jauh lebih jarang daripada wildcard terbatas, tetapi diperlukan saat dibutuhkan.
Batas bawah dan atas
Daftar <? Extends number> readList = new ArrayList <Integer> (); number n = readlist.get (0); Daftar <? super number> writeList = new ArrayList <BOCPOCE> (); writeList.Add (integer baru (5));
Yang pertama adalah daftar angka yang dapat dibaca.
Yang kedua adalah daftar angka yang dapat Anda tulis.
Wildcard yang tidak terikat
Akhirnya, konten daftar <?> Daftar bisa dari jenis apa saja, dan hampir sama dengan daftar <? memperluas objek>. Objek dapat dibaca kapan saja, tetapi konten tidak dapat ditulis ke daftar.
Wildcard di API Publik
Singkatnya, seperti yang disebutkan sebelumnya, wildcard sangat penting dalam menyembunyikan rincian implementasi dari penelepon, tetapi bahkan jika wildcards batas bawah tampaknya memberikan akses hanya baca, mereka tidak terjadi karena metode non-generik seperti menghapus (posisi int). Jika Anda menginginkan koleksi yang benar -benar tidak berubah, Anda dapat menggunakan metode ini di java.util.collection seperti Unmodifiblelist ().
Ingat wildcard saat menulis API. Secara umum, saat melewati jenis generik, Anda harus mencoba menggunakan wildcard. Ini memungkinkan lebih banyak penelepon untuk mengakses API.
Dengan menerima daftar <? Extends Number> Alih -alih Daftar <number>, metode berikut dapat dipanggil oleh berbagai jenis daftar:
Salinan kode adalah sebagai berikut: void removenegative (daftar <? Extends number> list);
Bangun tipe generik
Sekarang kita akan membahas pembangunan tipe generik kita sendiri. Kami akan menunjukkan beberapa contoh di mana jenis keamanan dapat ditingkatkan dengan menggunakan obat generik, dan kami juga akan membahas beberapa masalah umum saat menerapkan jenis generik.
Fungsi seperti koleksi
Contoh pertama dari kelas generik adalah contoh gaya koleksi. Pasangan memiliki dua parameter tipe, dan bidang adalah contoh tipe:
Pasangan kelas akhir publik <a, b> {final publik a pertama; final publik b kedua; pasangan publik (a pertama, b kedua) {this.first = first; this.second = kedua;}}Ini memungkinkan untuk mengembalikan dua item dari metode tanpa menulis kelas khusus untuk setiap kombinasi dari dua jenis. Cara lain adalah mengembalikan objek [], yang merupakan jenisnya tidak aman atau tidak rapi.
Dalam penggunaan berikut, kami mengembalikan file dan boolean dari metode ini. Klien dari metode ini dapat menggunakan bidang secara langsung tanpa jenis casting:
Pasangan publik <file, boolean> getFileAndwritestatus (string path) {// Buat file dan statusReturn pair baru <file, boolean> (file, status);} pair <file, boolean> hasil = getFileAnDwritestatus ("..."); file f = result.first; first; boolean writeable = result.second;Di luar koleksi
Dalam contoh berikut, obat generik digunakan untuk keamanan kompilasi tambahan. Dengan parameterisasi kelas DBFactory ke tipe rekan yang dibuat, Anda sebenarnya memaksa subkelas pabrik untuk mengembalikan subtipe spesifik dari rekan:
Kelas Publik Abstrak DbFactory <T memperluas dbpeer> {protected abstrak t createemptypeer (); Daftar publik <T> get (string constraint) {list <t> peers = new ArrayList <T> (); // database MagicReturn peers;}}Dengan mengimplementasikan DBFactory <Customer>, CustomerFactory harus mengembalikan pelanggan dari createemptypeer ():
Public Class CustomerFactory memperluas dbfactory <sust customer> {customer customer createemptypeer () {return new new customer ();}}Metode generik
Apakah Anda ingin memaksakan kendala pada tipe generik antara parameter dan antara parameter dan tipe pengembalian, Anda dapat menggunakan metode generik:
Misalnya, jika fungsi inversi yang ditulis terbalik secara posisi, maka metode generik mungkin tidak diperlukan. Namun, jika Anda ingin inversi mengembalikan daftar baru, Anda mungkin ingin jenis elemen dari daftar baru sama dengan jenis daftar yang masuk. Dalam hal ini, metode generik diperlukan:
Salin kode sebagai berikut: <T> Daftar <T> Reverse (Daftar <T> Daftar)
Konkret
Saat menerapkan kelas generik, Anda mungkin ingin membuat array t []. Karena obat generik diimplementasikan oleh penghapusan, ini tidak diperbolehkan.
Anda dapat mencoba casting objek [] ke t []. Tapi ini tidak aman.
Solusi konkret
Menurut konvensi tutorial generik, solusi ini menggunakan "token tipe". Dengan menambahkan parameter kelas <T> ke konstruktor, Anda dapat memaksa klien untuk memberikan objek kelas yang benar untuk parameter tipe kelas:
Public Class ArrayExample <T> {private Class <T> clazz; public arrayexample (class <t> clazz) {this.clazz = clazz;} public t [] getArray (ukuran int) {return (t []) array.newinstance (clazz, size);}}Untuk membangun arrayexample <string>, klien harus meneruskan string.class ke konstruktor karena jenis string.class adalah kelas <string>.
Memiliki objek kelas memungkinkan untuk membangun kelompok jenis elemen yang benar
Saya harap artikel ini akan membantu pemrograman Java semua orang.