Nombre maximum de paramètres dans la déclaration de méthode Java

133

Quel est le nombre maximum de paramètres qu'une méthode en Java peut avoir et pourquoi?

J'utilise Java 1.8 sur un système Windows 64 bits.

Toutes les réponses sur StackOverflow à ce sujet indiquent que la limite technique est de 255 paramètres sans préciser pourquoi.

Pour être précis, 255 pour les thisméthodes statiques et 254 pour les méthodes non statiques (ce sera la 255e dans ce cas).

Je pensais que cela pouvait être décrit dans une sorte de spécification et qu'il y avait simplement un nombre maximum de paramètres autorisés statiquement défini.

Mais ce n'était valable que pour intet tous les types 4 octets . J'ai fait quelques tests avec des longparamètres, et je n'ai pu déclarer que 127 paramètres dans ce cas.

Avec les Stringparamètres, le nombre autorisé que j'ai déduit des tests est de 255 (c'est peut-être parce que la taille de référence est de 4 octets en Java?).

Mais comme j'utilise un système 64 bits, la taille des références doit être de 8 octets de large et donc avec les Stringparamètres, le nombre maximum autorisé doit être de 127, similaire aux longtypes.

Comment cette limite est-elle exactement appliquée?

La limite a-t-elle quelque chose à voir avec la taille de pile de la méthode?

Remarque: Je ne vais pas vraiment utiliser ces nombreux paramètres dans aucune méthode, mais cette question est uniquement pour clarifier le comportement exact.

userv
la source
39
7, si vous ne voulez pas devenir fou avec la lisibilité. (Je sais ce que vous demandez réellement).
Adam
14
Je discuterais <= 4. Quelque chose de plus devrait probablement être enveloppé dans un objet.
Vivin Paliath le
4
Pourquoi est-ce une question intéressante? Si vous écrivez un programme et que vous atteignez cette limite, votre conception est erronée. Je ne comprends pas pourquoi une question aussi pratiquement inutile reçoit autant de votes positifs.
Jesper
20
@Jesper parce que cela remet en question la connaissance de la spécification JVM. Cette question ne demande pas "Comment faire ceci ou cela?" à la place, il questionne "Pourquoi j'ai besoin de ça?" ... +1 Question intéressante Userv
Amit
2
@amit exactement ce que je pensais. L'OP était simplement curieux à ce sujet.
Evan Carslake

Réponses:

110

Cette limite est définie dans la spécification JVM :

Le nombre de paramètres de méthode est limité à 255 par la définition d'un descripteur de méthode (§4.3.3), où la limite inclut une unité pour cela dans le cas des appels de méthode d'instance ou d'interface.

La section §4.3.3 donne quelques informations supplémentaires:

Un descripteur de méthode n'est valide que s'il représente des paramètres de méthode d'une longueur totale de 255 ou moins, où cette longueur inclut la contribution pour cela dans le cas des appels de méthode d'instance ou d'interface.

La longueur totale est calculée en additionnant les contributions des paramètres individuels, où un paramètre de type long ou double contribue pour deux unités à la longueur et un paramètre de tout autre type contribue pour une unité .

Vos observations étaient parfaites, les primitives de mot double ( long/ double) ont besoin de deux fois la taille des variables habituelles de 4 octets et des références d'instance d'objet de 4 octets .

En ce qui concerne la dernière partie de votre question relative aux systèmes 64 bits, la spécification définit le nombre d' unités qu'un paramètre contribue , cette partie de la spécification doit toujours être respectée même sur une plate-forme 64 bits, la JVM 64 bits accueillera 255 paramètres d'instance (comme votre 255 Strings) quelle que soit la taille du pointeur de l'objet interne.

Umberto Raimondi
la source
10
J'ajouterais à cette réponse que sur l'architecture 64 bits, la pile est également 64 bits. Ainsi, comme la limitation du nombre de paramètres est liée à la taille de la pile, la pile 64 bits permet de stocker les mêmes 255 références d'objet. Le traitement spécifique longet doubleindépendamment de l'architecture du système se produit dans de nombreux endroits de la spécification et semble être un vestige de l'ère 32 bits.
Sergei
J'étais en train de modifier juste cette partie :) D'accord, la spécification doit encore être respectée même sur différentes plates-formes.
Umberto Raimondi
1
Ouais, si le nombre de paramètres était fonction de la taille du mot, cela briserait la portabilité; vous ne pouvez pas compiler avec succès le même programme Java sur différentes architectures.
Vivin Paliath
3
Les Varargs sont transformés en tableau Object , ne peuvent être utilisés qu'une seule fois dans la liste des paramètres et occupent la dernière position. Compte tenu de tout cela, je dirais qu'en utilisant varargs, le nombre de paramètres peut être "étendu" à 254 + Integer.MAX_VALUE (au moins pour le programmeur ... les paramètres sont toujours 255), donc en utilisant cette astuce, vous pouvez avoir Integer. Paramètres d'objet MAX_VALUE.
Umberto Raimondi
1
@MrTsjolder Jetez un œil à cette réponse pour varargs.
Vivin Paliath
11

La section 4.3.3 de la spécification JVM contient les informations que vous recherchez:

Un descripteur de méthode n'est valide que s'il représente des paramètres de méthode d'une longueur totale de 255 ou moins, où cette longueur inclut la contribution pour cela dans le cas des appels de méthode d'instance ou d'interface. La longueur totale est calculée en additionnant les contributions des paramètres individuels, où un paramètre de type long ou double contribue pour deux unités à la longueur et un paramètre de tout autre type contribue pour une unité .

Par conséquent, il apparaît que le fait que la machine hôte soit 32 bits ou 64 bits n'a aucun effet sur le nombre de paramètres. Si vous remarquez, la documentation parle en termes d '"unités", où la longueur d'une "unité" est fonction de la taille du mot. Si le nombre de paramètres directement proportionnel à la taille du mot, il y aurait des problèmes de portabilité; vous ne pourriez pas compiler le même programme Java sur des architectures différentes (en supposant qu'au moins une méthode utilise le nombre maximum de paramètres sur l'architecture avec la plus grande taille de mot).

Vivin Paliath
la source
10

J'ai trouvé un numéro intéressant dans une newsletter à ce sujet, http://www.javaspecialists.eu/archive/Issue059.html

Le pool de constantes par classe ou par interface est limité à 65 535 entrées par le champ constant_pool_count de 16 bits de la structure ClassFile. Cela agit comme une limite interne sur la complexité totale d'une seule classe ou interface. La quantité de code par méthode non native et non abstraite est limitée à 65 536 octets par les tailles des index dans la table d'exception de l'attribut Code, dans l'attribut LineNumberTable et dans l'attribut LocalVariableTable.

Le plus grand nombre de variables locales dans le tableau de variables locales d'une trame créée lors de l'invocation d'une méthode est limité à 65535 par la taille de l'élément max_locals de l'attribut Code donnant le code de la méthode. Notez que les valeurs de type long et double sont chacune considérées comme réservant deux variables locales et contribuant deux unités vers la valeur max_locals, donc l'utilisation de variables locales de ces types réduit encore cette limite.

Le nombre de champs qui peuvent être déclarés par une classe ou une interface est limité à 65535 par la taille de l'élément fields_count de la structure ClassFile. Notez que la valeur de l'élément fields_count de la structure ClassFile n'inclut pas les champs hérités des superclasses ou des superinterfaces.

Matthew Brzezinski
la source