Sampai J2SE1.4, tidak mungkin untuk mendefinisikan metode dengan parameter nyata variabel dalam program Java - karena Java mensyaratkan bahwa jumlah dan jenis parameter nyata (argumen) dan parameter formal harus dicocokkan satu per satu, dan jumlah parameter formal ditetapkan saat mendefinisikan metode. Meskipun metode yang sama dapat disediakan dengan jumlah parameter formal yang berbeda melalui mekanisme kelebihan beban, ini masih tidak dapat mencapai tujuan memungkinkan kuantitas parameter nyata berubah secara sewenang -wenang.
Namun, semantik dari beberapa metode mensyaratkan bahwa mereka harus dapat menerima jumlah variabel parameter aktual - misalnya, metode utama yang terkenal harus dapat menerima semua parameter baris perintah sebagai parameter aktual, dan jumlah parameter baris perintah tidak dapat ditentukan terlebih dahulu.
Untuk masalah ini, secara tradisional, praktik "menggunakan array untuk membungkus parameter aktual yang akan dilewati" umumnya digunakan untuk menghadapinya.
1. Bungkus parameter dalam array
Praktek "Bungkus parameter aktual dengan array" dapat dibagi menjadi tiga langkah: pertama, tentukan parameter tipe array untuk metode ini; Kemudian ketika dipanggil, hasilkan array yang berisi semua parameter aktual untuk dilewati; Akhirnya, lulus array ini sebagai parameter nyata.
Pendekatan ini dapat secara efektif mencapai tujuan "membuat metode menerima parameter variabel", tetapi formulir saat menelepon tidak cukup sederhana.
Mekanisme VarArgs disediakan dalam J2SE1.5, memungkinkan definisi langsung parameter formal yang dapat cocok dengan beberapa parameter nyata. Dengan demikian, sejumlah variabel parameter aktual dapat dilewati dengan cara yang lebih sederhana.
Arti dari varargs
Secara umum, "varargs" berarti "variablenumberofarguments". Kadang -kadang itu hanya disebut "variabelgumen", tetapi karena istilah ini tidak menunjukkan apa yang bervariasi, artinya sedikit kabur.
2. Tentukan metode dengan parameter nyata variabel
Cukup tambahkan tiga berturut -turut "." (mis. "...", elipsis dalam kalimat dalam bahasa Inggris) antara "tipe" dan "nama parameter" dari parameter formal, dan dapat cocok dengan parameter aktual yang tidak pasti. Metode dengan parameter formal tersebut adalah metode dengan parameter nyata variabel.
Daftar 1: Metode dengan parameter nyata variabel
private static int sumup (int ... values) {}Perhatikan bahwa hanya parameter formal terakhir yang dapat didefinisikan sebagai "dapat mencocokkan parameter aktual yang tidak pasti". Oleh karena itu, hanya ada satu parameter formal tersebut dalam suatu metode. Selain itu, jika metode ini memiliki parameter formal lainnya, letakkan di posisi depan.
Kompiler akan mengonversi parameter formal terakhir menjadi parameter formal array secara rahasia dan membuat tanda dalam file kelas yang dikompilasi untuk menunjukkan bahwa ini adalah metode dengan parameter nyata variabel.
Daftar 2: Bentuk Rahasia Suatu Metode dengan Parameter Nyata Variabel
value private static int sumup (int []) {}Karena transformasi seperti itu, tidak mungkin untuk mendefinisikan metode untuk kelas ini yang konsisten dengan tanda tangan metode yang dikonversi.
Daftar 3: Kombinasi yang akan menyebabkan kesalahan kompilasi
private static int sumup (int ... values) {} private static int sumup (int [] values) {}3. Panggil metode dengan jumlah variabel parameter nyata
Selama parameter aktual yang akan dilewati ditulis satu per satu ke posisi yang sesuai, metode dengan jumlah variabel parameter nyata dapat dipanggil. Tidak ada langkah lain yang diperlukan.
Daftar 4: Beberapa parameter dapat dilewati
sumUp(1,3,5,7);
Secara tidak langsung, kompiler akan mengonversi proses panggilan ini menjadi bentuk "array yang dibungkus dalam parameter aktual":
Daftar 5: Pembuatan Array yang Tampak Tentu
sumUp(newint[]{1,2,3,4});
Selain itu, "yang tidak pasti" yang disebutkan di sini juga termasuk nol, jadi panggilan seperti itu masuk akal:
Daftar 6: Anda juga dapat melewati parameter nol aktual
sumUp();
Efek dari metode panggilan ini secara diam -diam dikonversi oleh kompiler setara dengan ini:
Listing 7: Zero Real Argumen sesuai dengan array kosong
sumUp(newint[]{});
Perhatikan bahwa masa lalu dilewatkan saat ini, bukan nol. Ini memungkinkan formulir terpadu ditangani tanpa harus mendeteksi situasi mana yang menjadi miliknya.
4. Proses parameter aktual dengan nomor variabel
Metode pemrosesan parameter aktual bernomor variabel pada dasarnya sama dengan metode pemrosesan parameter aktual array. Semua parameter aktual disimpan dalam array dengan nama yang sama dengan parameter formal. Menurut kebutuhan aktual, setelah membaca elemen -elemen dalam array ini, mengukus atau memasak, Anda dapat melakukan apa pun yang Anda inginkan.
Listing 8: Memproses argumen yang diterima
private static int sumup (int ... values) {int sum = 0; untuk (int i = 0; i <values.length; i ++) {sum+= values [i]; } return sum;}5. Teruskan jumlah variabel parameter
Kadang -kadang, setelah menerima satu set parameter nomor variabel, mereka harus diteruskan ke metode nomor variabel lain. Karena jumlah parameter aktual yang diterima selama pengkodean tidak dapat diketahui, praktik "menulis satu per satu ke lokasi di mana mereka seharusnya muncul" tidak layak. Namun, ini tidak berarti bahwa ini adalah tugas yang tidak dapat dipahami, karena ada cara lain untuk memanggil metode dengan parameter nyata variabel.
Di mata kompiler J2SE1.5, metode dengan parameter nyata variabel adalah kasus khusus dari metode ini dengan array parameter formal di akhir. Oleh karena itu, masukkan seluruh set parameter aktual untuk diteruskan ke dalam array di muka, dan kemudian lulus array ini sebagai parameter aktual terakhir ke metode dengan jumlah variabel parameter nyata, yang tidak akan menyebabkan kesalahan. Dengan fitur ini, penerusan dapat diselesaikan dengan lancar.
Daftar 9: Meneruskan parameter aktual yang diterima
kelas publik printfsample {public static void main (string [] args) {printout ("pi:%f e:%f/n", math.pi, math.e); } printout void private static (format string, objek ... args) {System.out.printf (format, args); }}6. Apakah ini sebuah array? Bukan array?
Meskipun di belakang layar, kompiler akan mengonversi parameter formal yang dapat cocok dengan parameter nyata yang tidak pasti menjadi parameter formal array; dan juga dapat menggunakan array untuk membungkus parameter aktual dan kemudian meneruskannya ke metode dengan jumlah variabel parameter nyata; Namun, ini tidak berarti bahwa tidak ada perbedaan antara "parameter formal yang dapat cocok dengan parameter nyata yang tidak pasti" dan "parameter formal array".
Perbedaan yang jelas adalah bahwa jika Anda memanggil metode yang parameter formal terakhirnya adalah parameter formal array dalam bentuk metode dengan jumlah variabel parameter nyata, itu hanya akan mengarah pada kesalahan kompilasi "tidak dapat diselesaikan".
Listing 10: Kesalahan kompilasi untuk "tidak dapat diselesaikan"
private static void testoverloading (int [] i) {system.out.println ("a");} public static void main (string [] args) {testoverloading (1, 2, 3); // kesalahan kompilasi}Untuk alasan ini, metode panggilan ringkas ini tidak dapat diadopsi secara langsung ketika metode panggilan yang hanya mendukung parameter pembungkus aktual dengan array (misalnya, yang tersisa dari desain perpustakaan pihak ketiga untuk J2SE1.5).
Jika Anda tidak dapat memodifikasi kelas asli dan menambahkan versi variabel dari jumlah parameter ke metode yang akan dipanggil, dan Anda ingin mengadopsi metode panggilan ringkas ini, Anda dapat menggunakan metode rekonstruksi "memperkenalkan Method" dan "pengantarelokextension" untuk memperkirakan tujuan.
7. Ketika sejumlah variabel argumen menemukan generik
Mekanisme "generik" baru telah ditambahkan ke J2SE1.5, yang dapat parameterisasi jenis dalam kondisi tertentu. Misalnya, saat menulis kelas, jenis parameter formal metode dapat diwakili oleh pengidentifikasi (seperti T). Adapun tipe apa yang diwakili oleh pengidentifikasi ini, ini ditentukan saat menghasilkan instance dari kelas ini. Mekanisme ini dapat digunakan untuk memberikan pengecekan kembali kode yang lebih lengkap dan pemeriksaan tipe kompilasi waktu yang lebih ketat.
Namun, mekanisme generik tidak dapat digunakan dengan jumlah variabel parameter formal. Jika jenis parameter formal yang cocok dengan argumen yang tidak pasti diwakili oleh pengidentifikasi, kompiler akan memberikan kesalahan "GenericArrayCreation".
Daftar 11: Saat Varargs bertemu generik
private static void testvarargs (t ... args) {// kesalahan kompilasi}Alasan untuk fenomena ini adalah kendala yang melekat pada mekanisme generik di J2SE1.5 - Sebuah instance dari jenis ini tidak dapat dibuat dengan jenis yang diwakili oleh pengidentifikasi. Sebelum versi Java mendukung tanpa kendala ini muncul, pada dasarnya tidak ada solusi yang baik untuk masalah ini.
Namun, praktik "bungkus dengan array" tradisional tidak tunduk pada kendala ini.
Listing 12: Solusi yang Dapat Dikompkan
private static void testvarargs (t [] args) {for (int i = 0; i <args.length; i ++) {System.out.println (args [i]); }}8. Masalah seleksi dalam kelebihan beban
Java mendukung mekanisme "kelebihan beban", yang memungkinkan banyak metode berbeda di kelas yang sama hanya memiliki daftar parameter formal. Kemudian, kompiler memilih metode mana yang akan dieksekusi berdasarkan parameter aktual pada saat panggilan.
Pilihan tradisional pada dasarnya didasarkan pada prinsip "orang khusus lebih disukai". Keistimewaan suatu metode tergantung pada jumlah kondisi yang perlu dipenuhi agar dapat berjalan dengan lancar. Semakin banyak kondisi yang Anda butuhkan, semakin istimewa.
Setelah pengenalan mekanisme Varargs, prinsip ini masih berlaku, tetapi masalah yang harus dipertimbangkan diperkaya - secara tradisional, di antara berbagai versi metode yang kelebihan beban, hanya mereka yang parameter morfologis dan parameter nyata yang persis sama untuk dipertimbangkan lebih lanjut. Namun, setelah pengenalan mekanisme VarArgs, dimungkinkan untuk mencocokkan kedua versi, dan tidak ada perbedaan dalam aspek lain, hanya saja satu parameter nyata memiliki angka tetap dan parameter nyata lainnya memiliki nomor variabel.
Dalam hal ini, aturan penentuan yang digunakan adalah bahwa "Versi dengan jumlah parameter nyata yang tetap lebih diutamakan daripada versi dengan jumlah variabel parameter nyata".
Listing 13: Versi dengan jumlah parameter nyata tetap lebih disukai
Jika, dalam tampilan kompiler, beberapa metode memiliki prioritas yang sama, itu akan macet dalam keadaan di mana ia tidak dapat membuat pilihan tentang metode mana yang akan dihubungi. Dalam hal ini, ini akan menghasilkan kesalahan kompilasi "Referenceto yang disebut nama metode isambiguy" dan menunggu dengan sabar untuk beberapa modifikasi untuk menghindari kedatangan kode sumber baru yang membingungkan.
Setelah pengenalan mekanisme Varargs, situasi ini yang dapat menyebabkan kebingungan telah meningkat sedikit lebih banyak. Misalnya, mungkin ada dua versi yang dapat cocok, yang persis sama dalam aspek lain, dan kedua konflik dengan jumlah variabel parameter nyata terjadi.
OverloadingSamplea kelas publik {public static void main (string [] args) {testoverloading (1); // cetak atestoverloading (1, 2); // cetak btestoverloading (1, 2, 3); // cetak c} private static estateOverLoading (int i) {out.out.oUnt.printer j) {System.out.println ("b");} private static void testoverloading (int i, int ... more) {System.out.println ("c");}}Jika, dalam tampilan kompiler, beberapa metode memiliki prioritas yang sama, itu akan macet dalam keadaan di mana ia tidak dapat membuat pilihan tentang metode mana yang akan dihubungi. Dalam hal ini, ini akan menghasilkan kesalahan kompilasi "Referenceto yang disebut nama metode isambiguy" dan menunggu dengan sabar untuk beberapa modifikasi untuk menghindari kedatangan kode sumber baru yang membingungkan.
Setelah pengenalan mekanisme Varargs, situasi ini yang dapat menyebabkan kebingungan telah meningkat sedikit lebih banyak. Misalnya, mungkin ada dua versi yang dapat cocok, yang persis sama dalam aspek lain, dan kedua konflik dengan jumlah variabel parameter nyata terjadi.
Daftar 14: Tidak peduli apa, sulit bagi kompiler
Public Class OverloadingsampleB {public static void main (string [] args) {testoverloading (1, 2, 3); // kesalahan kompilasi} private static void testoverloading (objek ... args) {}}Selain itu, karena ada mekanisme "autoboxing/auto-unboxing" di J2SE1.5, ada kemungkinan bahwa kedua versi dapat cocok, dan jumlah parameter nyata adalah variabel, dan aspek-aspek lainnya persis sama. Hanya saja satu parameter nyata yang dapat diterima adalah tipe dasar, sedangkan parameter nyata yang dapat diterima lainnya adalah konflik antara kelas paket.
Daftar 15: Masalah baru dari Autoboxing/Auto-Unboxing
OverloadingSamplec kelas publik {public static void main (string [] args) {/* Kesalahan kompilasi*/testoverloading (1, 2);/* atau kesalahan kompilasi*/testoverloading (integer baru (1), integer baru {}} {} {} {{} {{private) {{private void void private void private (int ... {{{{private) private private private private (int ...9. Ringkasan
Dibandingkan dengan metode "dibungkus dengan array", metode nyata dengan parameter nyata variabel lebih sederhana dan memiliki makna yang lebih jelas saat menelepon. Namun, mekanisme ini juga memiliki keterbatasan sendiri dan bukan solusi yang sempurna.
Di atas adalah semua penjelasan terperinci tentang kode parameter panjang variabel di Java, saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke situs ini:
Penjelasan terperinci tentang parameter implisit dan instance parameter tampilan di java
Implementasi Pemrograman Java dari Penjelasan Rinci Penyortiran dan Optimasi Cepat
Dekripsi Enkripsi Java dan Contoh Kode Lengkap Tanda Tangan Digital
Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!