Numero massimo di parametri nella dichiarazione del metodo Java


133

Qual è il numero massimo di parametri che può avere un metodo in Java e perché?

Sto usando Java 1.8 su un sistema Windows a 64 bit.

Tutte le risposte su StackOverflow a riguardo affermano che il limite tecnico è di 255 parametri senza specificare il perché.

Per essere precisi, 255 per i thismetodi statici e 254 per i metodi non statici ( sarà il 255 ° in questo caso).

Ho pensato che questo potesse essere descritto in una sorta di specifica e che ci fosse semplicemente un numero massimo di parametri definito staticamente consentito.

Ma questo era valido solo per inttutti i tipi di 4 byte . Ho fatto alcuni test con longparametri e sono stato in grado di dichiarare solo 127 parametri in quel caso.

Con i Stringparametri, il numero consentito che ho dedotto dal test è 255 (potrebbe essere perché la dimensione di riferimento è 4 byte in Java?).

Ma dal momento che sto usando un sistema a 64 bit, la dimensione dei riferimenti dovrebbe essere larga 8 byte e quindi con i Stringparametri il numero massimo consentito dovrebbe essere 127, simile ai longtipi.

Come viene applicato esattamente questo limite?

Il limite ha qualcosa a che fare con la dimensione dello stack del metodo?

Nota: non userò davvero questi molti parametri in nessun metodo, ma questa domanda serve solo a chiarire il comportamento esatto.


39
7, se non vuoi impazzire con la leggibilità. (So ​​cosa stai effettivamente chiedendo).
Adam,

14
Direi <= 4. Qualcosa di più dovrebbe probabilmente essere racchiuso in un oggetto.
Vivin Paliath,

4
Perché questa è una domanda interessante? Se stai scrivendo un programma e stai raggiungendo questo limite, il tuo design è sbagliato. Non capisco perché una domanda così praticamente inutile ottenga così tanti voti positivi.
Jesper,

20
@Jesper perché questa domanda mette in discussione la conoscenza delle specifiche JVM. Questa domanda non chiede "Come fare questo o quello?" invece domande "perché ho bisogno di questo?" ... 1 Interessante domanda userv
Amit

2
@ Esatto esattamente quello che stavo pensando. L'OP era solo curioso.
Evan Carslake,

Risposte:


110

Tale limite è definito nella specifica JVM :

Il numero di parametri del metodo è limitato a 255 dalla definizione di un descrittore di metodo (§4.3.3), in cui il limite include un'unità per questo in caso di invocazioni di metodi di istanza o interfaccia.

La sezione §4.3.3 fornisce alcune informazioni aggiuntive:

Un descrittore di metodo è valido solo se rappresenta parametri di metodo con una lunghezza totale di 255 o inferiore, laddove tale lunghezza includa il contributo per questo in caso di invocazioni di metodi di istanza o interfaccia.

La lunghezza totale viene calcolata sommando i contributi dei singoli parametri, in cui un parametro di tipo lungo o doppio contribuisce alla lunghezza di due unità e un parametro di qualsiasi altro tipo contribuisce a un'unità .

Le tue osservazioni sono state esatte, le primitive a doppia parola ( long/ double) necessitano di dimensioni doppie rispetto alle solite variabili di 4 byte e riferimenti di istanza di oggetti di 4 byte .

Per quanto riguarda l'ultima parte della tua domanda relativa ai sistemi a 64 bit, la specifica definisce il numero di unità che un parametro contribuisce , che parte della specifica deve ancora essere rispettata anche su una piattaforma a 64 bit, la JVM a 64 bit ospiterà 255 parametri di istanza (come il tuo 255 Strings) indipendentemente dalle dimensioni del puntatore dell'oggetto interno.


10
Aggiungerei a questa risposta che sull'architettura a 64 bit lo stack è anche a 64 bit. Pertanto, poiché la limitazione sul conteggio dei parametri è legata alla dimensione dello stack, lo stack a 64 bit consente di memorizzare gli stessi 255 riferimenti oggetto. Il trattamento specifico longe doubleindipendentemente dall'architettura del sistema si verifica in molti punti della specifica e sembra essere un residuo dell'era a 32 bit.
Sergei,

Stavo modificando proprio quella parte :) D'accordo, le specifiche devono ancora essere rispettate anche su piattaforme diverse.
Umberto Raimondi,

1
Sì, se il numero di parametri fosse una funzione della dimensione delle parole, ciò spezzerebbe la portabilità; non è stato possibile compilare correttamente lo stesso programma Java su architetture diverse.
Vivin Paliath,

3
I vararg vengono trasformati in un array di oggetti , possono essere utilizzati solo una volta nell'elenco dei parametri e occupano l'ultima posizione. Considerando tutto ciò, direi che usando varargs il numero di parametri può essere "esteso" a 254 + Integer.MAX_VALUE (almeno per il programmatore ... i parametri sono ancora 255), quindi usando quel trucco puoi avere Integer. MAX_VALUE parametri oggetto.
Umberto Raimondi,

1
@MrTsjolder Dai un'occhiata a questa risposta per varargs.
Vivin Paliath,

11

La sezione 4.3.3 della specifica JVM contiene le informazioni che stai cercando:

Un descrittore di metodo è valido solo se rappresenta parametri di metodo con una lunghezza totale di 255 o inferiore, laddove tale lunghezza includa il contributo per questo in caso di invocazioni di metodi di istanza o interfaccia. La lunghezza totale viene calcolata sommando i contributi dei singoli parametri, in cui un parametro di tipo lungo o doppio contribuisce alla lunghezza di due unità e un parametro di qualsiasi altro tipo contribuisce a un'unità .

Pertanto sembra che il fatto che la macchina host sia a 32 o 64 bit non ha alcun effetto sul numero di parametri. Se noti, la documentazione parla in termini di "unità", in cui la lunghezza di una "unità" è una funzione della dimensione della parola. Se il numero di parametri direttamente proporzionale alla dimensione della parola, ci sarebbero problemi di portabilità; non saresti in grado di compilare lo stesso programma Java su architetture diverse (supponendo che almeno un metodo abbia utilizzato il numero massimo di parametri sull'architettura con dimensioni della parola maggiori).


10

Ho trovato un interessante numero di una newsletter su questo, http://www.javaspecialists.eu/archive/Issue059.html

Il pool di costanti per classe o per interfaccia è limitato a 65535 voci dal campo constant_pool_count a 16 bit della struttura ClassFile. Questo funge da limite interno alla complessità totale di una singola classe o interfaccia. La quantità di codice per metodo non nativo e non astratto è limitata a 65536 byte dalle dimensioni degli indici nella tabella exception_table dell'attributo Code, nell'attributo LineNumberTable e nell'attributo LocalVariableTable.

Il maggior numero di variabili locali nell'array di variabili locali di un frame creato in seguito all'invocazione di un metodo è limitato a 65535 dalla dimensione dell'elemento max_locals dell'attributo Code che fornisce il codice del metodo. Si noti che i valori di tipo long e double sono considerati ciascuno per riservare due variabili locali e contribuire con due unità verso il valore max_locals, quindi l'uso di variabili locali di quel tipo riduce ulteriormente questo limite.

Il numero di campi che possono essere dichiarati da una classe o un'interfaccia è limitato a 65535 dalla dimensione dell'elemento fields_count della struttura ClassFile. Si noti che il valore dell'elemento fields_count della struttura ClassFile non include i campi ereditati da superclassi o superinterfacce.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.