Jumlah maksimum parameter dalam deklarasi metode Java

133

Berapa jumlah maksimum parameter yang dimiliki oleh suatu metode di Java dan mengapa?

Saya menggunakan Java 1.8 pada sistem Windows 64-bit.

Semua jawaban di StackOverflow tentang ini mengatakan bahwa batas teknisnya adalah 255 parameter tanpa menyebutkan alasannya.

Tepatnya, 255 untuk thismetode statis dan 254 untuk metode non-statis ( akan menjadi 255 dalam kasus ini).

Saya pikir ini bisa dijelaskan dalam semacam spesifikasi dan bahwa hanya ada jumlah maksimum parameter statis yang diizinkan.

Tapi ini hanya berlaku untuk intdan semua tipe 4-byte . Saya melakukan beberapa tes dengan longparameter, dan saya hanya bisa mendeklarasikan 127 parameter dalam kasus itu.

Dengan Stringparameter, jumlah yang diizinkan yang saya simpulkan dari pengujian adalah 255 (mungkin karena ukuran referensi adalah 4 byte di Jawa?).

Tetapi karena saya menggunakan sistem 64-bit, ukuran referensi harus lebar 8 byte dan dengan Stringparameter, jumlah maksimum yang dibolehkan adalah 127, mirip dengan longtipe.

Bagaimana batas ini diterapkan secara tepat?

Apakah batas itu ada hubungannya dengan ukuran tumpukan metode?

Catatan: Saya tidak benar-benar akan menggunakan banyak parameter ini dalam metode apa pun, tetapi pertanyaan ini hanya untuk memperjelas perilaku yang tepat.

Userv
sumber
39
7, jika Anda tidak ingin menjadi gila dengan keterbacaan. (Saya tahu apa yang sebenarnya Anda tanyakan).
Adam
14
Saya akan berdebat <= 4. Sesuatu yang lebih mungkin harus dibungkus menjadi suatu objek.
Vivin Paliath
4
Mengapa ini pertanyaan yang menarik? Jika Anda menulis program dan Anda mencapai batas ini, maka desain Anda salah. Saya tidak mengerti mengapa pertanyaan praktis yang tidak berguna ini mendapatkan begitu banyak masalah.
Jesper
20
@Jesper karena pertanyaan ini mempertanyakan pengetahuan tentang spesifikasi JVM. Pertanyaan ini tidak menanyakan "Bagaimana melakukan ini atau itu?" alih-alih, pertanyaan "Mengapa saya perlu itu?" ... +1 Pertanyaan menarik Userv
Amit
2
@it persis apa yang saya pikirkan. OP hanya ingin tahu tentang hal itu.
Evan Carslake

Jawaban:

110

Batas itu didefinisikan dalam Spesifikasi JVM :

Jumlah parameter metode dibatasi hingga 255 oleh definisi deskriptor metode (§4.3.3), di mana batasnya mencakup satu unit untuk ini dalam kasus instance atau metode antarmuka antarmuka.

Bagian §4.3.3 memberikan beberapa informasi tambahan:

Deskriptor metode hanya valid jika mewakili parameter metode dengan panjang total 255 atau kurang, di mana panjang itu termasuk kontribusi untuk ini dalam kasus instance atau metode antarmuka.

Panjang total dihitung dengan menjumlahkan kontribusi parameter individu, di mana parameter tipe panjang atau ganda memberikan kontribusi dua unit untuk panjang dan parameter dari tipe lain berkontribusi satu unit .

Pengamatan Anda sangat tepat, kata primitif ganda ( long/ double) membutuhkan dua kali ukuran variabel 4 byte biasa dan 4 contoh referensi objek objek .

Mengenai bagian terakhir dari pertanyaan Anda terkait dengan sistem 64bit, spesifikasi menentukan berapa banyak unit yang dikontribusikan parameter , bagian dari spesifikasi itu masih harus dipenuhi bahkan pada platform 64bit, JVM 64bit akan mengakomodasi 255 parameter instance (seperti 255 Anda Strings) terlepas dari ukuran pointer objek internal.

Umberto Raimondi
sumber
10
Saya akan menambahkan jawaban ini bahwa pada arsitektur 64 bit stack juga 64 bit. Jadi, karena batasan pada jumlah parameter terikat ukuran stack, stack 64-bit memungkinkan penyimpanan 255 objek referensi yang sama. Perlakuan khusus longdan doubleterlepas dari arsitektur sistem terjadi di banyak tempat spesifikasi dan tampaknya merupakan sisa dari era 32-bit.
Sergei
Saya sedang dalam proses mengedit hanya bagian itu :) Setuju, spek masih harus dihormati bahkan pada platform yang berbeda.
Umberto Raimondi
1
Ya, jika jumlah parameter adalah fungsi dari ukuran kata, maka itu akan merusak portabilitas; Anda tidak dapat mengkompilasi program Java yang sama dengan sukses pada arsitektur yang berbeda.
Vivin Paliath
3
Varargs diubah menjadi Object array, hanya dapat digunakan satu kali dalam daftar parameter dan menempati posisi terakhir. Mempertimbangkan semua ini, saya akan mengatakan bahwa menggunakan varargs jumlah parameter dapat "diperluas" ke 254 + Integer.MAX_VALUE (setidaknya untuk programmer ... parameter masih 255), jadi dengan menggunakan trik itu Anda dapat memiliki Integer. MAX_VALUE parameter objek.
Umberto Raimondi
1
@ Mrjjolder Lihatlah jawaban ini untuk varargs.
Vivin Paliath
11

Bagian 4.3.3 dari spesifikasi JVM memiliki informasi yang Anda cari:

Deskriptor metode hanya valid jika mewakili parameter metode dengan panjang total 255 atau kurang, di mana panjang itu termasuk kontribusi untuk ini dalam kasus instance atau metode antarmuka. Panjang total dihitung dengan menjumlahkan kontribusi parameter individu, di mana parameter tipe panjang atau ganda memberikan kontribusi dua unit untuk panjang dan parameter dari tipe lain berkontribusi satu unit .

Oleh karena itu tampak bahwa apakah mesin-host adalah 32-bit atau 64-bit tidak berpengaruh pada jumlah parameter. Jika Anda perhatikan, dokumentasi berbicara dalam istilah "unit", di mana panjang satu "unit" adalah fungsi dari ukuran kata. Jika jumlah parameter berbanding lurus dengan ukuran kata, akan ada masalah portabilitas; Anda tidak akan dapat mengkompilasi program Java yang sama pada arsitektur yang berbeda (dengan asumsi bahwa setidaknya satu metode menggunakan jumlah maksimum parameter pada arsitektur dengan ukuran kata yang lebih besar).

Vivin Paliath
sumber
10

Saya menemukan masalah menarik dari buletin tentang ini, http://www.javaspecialists.eu/archive/Issue059.html

Kelompok konstan per-kelas atau per-antarmuka dibatasi hingga 65535 entri oleh bidang constant_pool_count 16-bit dari struktur ClassFile. Ini bertindak sebagai batas internal pada kompleksitas total dari satu kelas atau antarmuka. Jumlah kode per non-asli, metode non-abstrak dibatasi hingga 65536 byte dengan ukuran indeks dalam exception_table atribut Code, dalam atribut LineNumberTable, dan dalam atribut LocalVariableTable.

Jumlah variabel lokal terbesar dalam array variabel lokal dari sebuah frame yang dibuat pada saat pemanggilan metode dibatasi hingga 65535 dengan ukuran item max_locals dari atribut Code yang memberikan kode metode tersebut. Perhatikan bahwa nilai tipe long dan double masing-masing dianggap sebagai cadangan dua variabel lokal dan berkontribusi dua unit terhadap nilai max_locals, jadi penggunaan variabel lokal dari tipe-tipe tersebut semakin mengurangi batas ini.

Jumlah bidang yang dapat dideklarasikan oleh kelas atau antarmuka dibatasi hingga 65535 dengan ukuran item fields_count dari struktur ClassFile. Perhatikan bahwa nilai item fields_count dari struktur ClassFile tidak termasuk bidang yang diwarisi dari kacamata super atau superinterfaces.

Matthew Brzezinski
sumber