Java yöntemi bildirimindeki maksimum parametre sayısı


133

Java'da bir yöntemin sahip olabileceği maksimum parametre sayısı nedir ve neden?

64 bit Windows sisteminde Java 1.8 kullanıyorum.

Bu konuda StackOverflow'daki tüm cevaplar, teknik sınırın nedenini belirtmeden 255 parametre olduğunu söylüyor.

Kesin olmak gerekirse, statik için 255 ve statik olmayan için 254 ( thisbu durumda 255.) Olacaktır.

Bunun bir tür spesifikasyonda tanımlanabileceğini ve sadece statik olarak tanımlanmış maksimum parametre sayısına izin verildiğini düşündüm.

Ancak bu yalnızca int4 baytlık türlerin tümü için geçerlidir . longParametrelerle bazı testler yaptım ve bu durumda sadece 127 parametre bildirebildim.

İle Stringparametreler test çıkarılabilir izin numarayı (referans boyutu Java 4 bayt olmasından kaynaklanabilir?) 255'tir.

Ancak 64 bit sistem kullandığım için, referans boyutu 8 bayt genişliğinde olmalı ve bu nedenle Stringparametrelerle izin verilen maksimum sayı 127, longtürlere benzer olmalıdır .

Bu sınır tam olarak nasıl uygulanır?

Sınırın yöntemin yığın boyutu ile bir ilgisi var mı ?

Not: Bu parametrelerin hiçbirini gerçekten herhangi bir yöntemde kullanmayacağım, ancak bu soru sadece tam davranışı netleştirmek içindir.


39
7, okunabilirlik ile delirmek istemiyorsanız. (Aslında ne istediğini biliyorum).
Adam

14
Tartışırdım <= 4. Daha fazla bir şey muhtemelen bir nesneye sarılmalıdır.
Vivin Paliath

4
Bu neden ilginç bir soru? Bir program yazıyorsanız ve bu sınıra ulaşıyorsanız, tasarımınız yanlıştır. Pratik olarak işe yaramaz bir sorunun neden bu kadar çok oy aldığını anlamıyorum.
Jesper

20
@Jesper çünkü bu sorular JVM spesifikasyonu hakkındaki bilgileri sorguluyor. Bu soru "Bunu nasıl ya da böyle yapmalı?" bunun yerine "Neden buna ihtiyacım var?" sorusunu soruyor ... +1 İlginç soru Userv
Amit

2
@ tam olarak düşündüğüm şeyle. OP sadece merak ediyordu.
Evan Carslake

Yanıtlar:


110

Bu sınır JVM Spesifikasyonunda tanımlanmıştır :

Yöntem parametrelerinin sayısı, bir yöntem tanımlayıcısı (§4.3.3) tanımıyla 255 ile sınırlıdır ; burada sınır, örnek veya arabirim yöntemi çağrıları durumunda bunun için bir birim içerir .

Bölüm §4.3.3 bazı ek bilgiler verir:

Bir yöntem tanımlayıcısı, yalnızca toplam uzunluğu 255 veya daha az olan yöntem parametrelerini temsil ediyorsa geçerlidir; bu uzunluk, örnek veya arabirim yöntemi çağrıları durumunda bunun için katkıyı içerir .

Toplam uzunluk, ayrı ayrı parametrelerin katkılarının toplanmasıyla hesaplanır, burada uzun veya çift tip bir parametrenin uzunluğa iki birim kattığı ve başka herhangi bir türün parametresinin bir birime katkıda bulunduğu .

Gözlemleriniz yerinde, çift kelimeli ilkel ( long/ double) normal 4 bayt değişkenleri ve 4 bayt nesne örneği referanslarının iki katı büyüklüğüne ihtiyaç duyuyordu .

64bit sistemlerle ilgili sorunuzun son kısmı ile ilgili olarak, şartname bir parametrenin kaç üniteye katkıda bulunduğunu tanımlar, şartnamenin bir kısmına 64bit'lik bir platformda bile uyulması gerekir , 64bit JVM 255 örnek parametresini (255 Strings) dahili nesnenin işaretçi boyutundan bağımsız olarak.


10
Bu cevaba 64 bit mimaride yığının da 64 bit olduğunu ekliyorum. Bu nedenle, parametre sayısındaki sınırlama yığın boyutuna bağlı olduğundan, 64 bit yığın aynı 255 nesne başvurusunun depolanmasına izin verir. Sistem mimarisinin özel muamelesi longve doublesistem mimarisine bakılmaksızın, spesifikasyonun birçok yerinde meydana gelir ve 32 bitlik bir dönemin kalıntısı gibi görünmektedir.
Sergei

Sadece o kısmı düzenleme sürecindeydim :) Kabul ediyorum, spesifikasyonlar farklı platformlarda bile hala saygı duyulmalı.
Umberto Raimondi

1
Evet, parametre sayısı kelime boyutunun bir fonksiyonu olsaydı, bu taşınabilirliği bozardı; aynı Java programını farklı mimarilerde başarıyla derleyemezdiniz.
Vivin Paliath

3
Varargs bir Object dizisine dönüştürülür , parametre listesinde yalnızca bir kez kullanılabilir ve son konumu işgal eder. Tüm bu göz önüne alındığında, varargs kullanarak parametre sayısı 254 + Integer.MAX_VALUE (en azından programcı ... parametreleri hala 255) için "genişletilebilir" söyleyebilirim, bu yüzden bu hile kullanarak tamsayı olabilir. MAX_VALUE nesne parametresi.
Umberto Raimondi

1
@MrTsjolder varargs için bu cevaba bir göz atın .
Vivin Paliath

11

JVM spesifikasyonunun Bölüm 4.3.3'ü aradığınız bilgilere sahiptir:

Bir yöntem tanımlayıcısı, yalnızca toplam uzunluğu 255 veya daha az olan yöntem parametrelerini temsil ediyorsa geçerlidir; bu uzunluk, örnek veya arabirim yöntemi çağrıları durumunda bunun için katkıyı içerir. Toplam uzunluk, ayrı ayrı parametrelerin katkılarının toplanmasıyla hesaplanır, burada uzun veya çift tip bir parametrenin uzunluğa iki birim kattığı ve başka herhangi bir türün parametresinin bir birime katkıda bulunduğu .

Bu nedenle, ana makine 32-bit mi yoksa 64-bit mi olsun parametre sayısı üzerinde hiçbir etkisi yoktur. Dikkat ederseniz, belgeler bir birimin uzunluğunun kelime boyutunun bir işlevi olduğu "birimler" cinsinden konuşur. Parametre sayısı kelime boyutuyla doğru orantılıysa, taşınabilirlik sorunları olacaktır; aynı Java programını farklı mimarilerde derleyemezsiniz (en az bir yöntemin mimaride daha büyük kelime boyutuna sahip maksimum parametre sayısını kullandığını varsayarak).


10

Bu konuda bir bültenden ilginç bir sorun buldum, http://www.javaspecialists.eu/archive/Issue059.html

Sınıf başına veya arabirim başına sabit havuz, ClassFile yapısının 16-bit constant_pool_count alanı tarafından 65535 girişle sınırlıdır. Bu, tek bir sınıfın veya arayüzün toplam karmaşıklığı için dahili bir sınır görevi görür. Yerel olmayan, soyut olmayan yöntem başına kod miktarı, Code özniteliğinin exception_table, LineNumberTable özniteliği ve LocalVariableTable özniteliğindeki indekslerin boyutlarıyla 65536 bayt ile sınırlıdır.

Bir yöntemin başlatılması üzerine oluşturulan bir çerçevenin yerel değişkenler dizisindeki en büyük yerel değişken sayısı, yöntemin kodunu veren Code özniteliğinin max_locals öğesinin boyutu ile 65535 ile sınırlıdır. Uzun ve çift tip değerlerin her birinin iki yerel değişken ayırdığı ve max_locals değerine iki birim kattığı düşünülür, bu nedenle bu tür yerel değişkenlerin kullanılması bu sınırı daha da azaltır.

Bir sınıf veya arabirim tarafından bildirilebilecek alan sayısı, ClassFile yapısının fields_count öğesinin boyutuyla 65535 ile sınırlıdır. ClassFile yapısının fields_count öğesinin değerinin, üst sınıflardan veya üst sınıflardan devralınan alanları içermediğini unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.