Quel est le nombre maximal de paramètres qu'une méthode peut avoir Java) 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 spécifier pourquoi.
Pour être précis, 255 pour les méthodes statiques et 254 pour les méthodes non statiques (this
sera la 255ème dans ce cas).
J'ai pensé que cela pourrait être décrit dans une sorte de spécification et qu'il existe simplement un nombre maximum de paramètres autorisés statiquement.
Mais cela n’est valable que pour int
et tous les types de 4 octets. J'ai fait quelques tests avec long
paramètres, et je n'ai pu déclarer que 127 paramètres dans ce cas.
Avec String
paramètres, le nombre autorisé que j'ai déduit des tests est de 255 (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. Ainsi, avec les paramètres String
, le nombre maximal autorisé doit être 127, similaire à long
types.
Comment cette limite est-elle appliquée exactement?
La limite a-t-elle quelque chose à voir avec la taille de la pile de la méthode?
Remarque: je ne vais pas vraiment utiliser ces nombreux paramètres dans aucune méthode, mais cette question ne vise qu'à clarifier le comportement exact.
Cette limite est définie dans le 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), la limite comprenant une unité pour this dans le cas d'invocations de méthodes d'instance ou d'interface.
La section §4.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 dont la longueur totale est inférieure ou égale à 255, cette longueur incluant la contribution pour this dans le cas d'invocations de méthodes d'instance ou d'interface.
La longueur totale est calculée en faisant la somme des contributions des paramètres individuels lorsqu'un paramètre de type long ou double contribue à la longueur de deux unités et qu'un paramètre de tout autre type contribue à une unité .
Vos observations étaient sur place, les doubles primitives Word (long
/double
) nécessitent le double de la taille des variables usuelles de 4 octets et 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 de unités auxquelles un paramètre contribue, cette partie de la spécification doit toujours être respectée. même sur une plate-forme 64 bits, la machine virtuelle Java 64 bits accueillera 255 paramètres d'instance (comme votre 255 Strings
) quelle que soit la taille du pointeur de l'objet interne.
Section 4.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 dont la longueur totale est inférieure ou égale à 255, cette longueur incluant la contribution correspondante dans le cas d'invocations 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 le type long ou double contribue à deux unités à la longueur et a Le paramètre de tout autre type contribue à une unité .
Par conséquent, il semble que le fait que la machine hôte soit 32 bits ou 64 bits n’a pas d’incidence sur le nombre de paramètres. Si vous remarquez, la documentation parle en termes d '"unités", la longueur d'une "unité" étant fonction de la taille du mot. Si le nombre de paramètres directement proportionnels à la taille de Word, il y aurait des problèmes de portabilité; vous ne pourriez pas compiler le même programme Java sur différentes architectures (en supposant qu’au moins une méthode utilise le nombre maximal de paramètres de l’architecture de taille Word supérieure).
J'ai trouvé un problème intéressant dans un bulletin d'information à ce sujet, http://www.javaspecialists.eu/archive/Issue059.html
Le pool constant par classe ou par interface est limité à 65 535 entrées par le champ constant_pool_count 16 bits de la structure ClassFile. Cela agit comme une limite interne sur la complexité totale d'une classe ou d'une interface unique. La quantité de code par méthode non native et non abstraite est limitée à 65 536 octets par la taille des index dans la table exception_table 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'appel 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 considérées chacune comme réservant deux variables locales et contribuent de deux unités à la valeur max_locals, de sorte que l'utilisation de variables locales de ces types réduit davantage cette limite
Le nombre de champs pouvant ê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 de superclasses ou de superinterfaces.