Java 方法声明中的最大参数数

Maximum number of parameters in Java method declaration

Java 中的方法最多可以有多少个参数,为什么?

我在 64 位 Windows 系统上使用 Java 1.8。

Whosebug 上关于这个的所有答案都说技术限制是 255 个参数,但没有说明原因。

准确地说,静态方法有 255 个,非静态方法有 254 个(this 在这种情况下将是第 255 个)方法。

我认为这可以在某种规范中进行描述,并且只是静态定义了允许的最大参数数。

但这仅对 int 和所有 4 字节类型 有效。 我用 long 参数做了一些测试,在那种情况下我只能声明 127 个参数。

使用String参数,我测试得出的允许数量是255(可能是因为Java中引用大小是4字节?)。

但由于我使用的是 64 位系统,引用大小应为 8 字节宽,因此对于 String 参数,最大允许数量应为 127,类似于 long 类型。

这个限制究竟是如何应用的?

限制是否与方法的堆栈大小有关?

注意:我真的不会在任何方法中使用这么多参数,但这个问题只是为了澄清确切的行为。

该限制在 JVM Specification 中定义:

The number of method parameters is limited to 255 by the definition of a method descriptor (§4.3.3), where the limit includes one unit for this in the case of instance or interface method invocations.

§4.3.3 部分提供了一些附加信息:

A method descriptor is valid only if it represents method parameters with a total length of 255 or less, where that length includes the contribution for this in the case of instance or interface method invocations.

The total length is calculated by summing the contributions of the individual parameters, where a parameter of type long or double contributes two units to the length and a parameter of any other type contributes one unit.

您的观察是正确的,双字原语 (long/double) 需要两倍于通常的 4 字节变量 和 4 字节对象实例引用的大小.

关于你问题的最后一部分与 64 位系统有关,规范定义了一个参数贡献了多少单位,那部分规范必须仍然是符合 即使在 64 位平台上,64 位 JVM 也将容纳 255 个实例参数(就像你的 255 Strings),而不管内部对象的指针大小。

JVM规范的

Section 4.3.3有你要找的资料:

A method descriptor is valid only if it represents method parameters with a total length of 255 or less, where that length includes the contribution for this in the case of instance or interface method invocations. The total length is calculated by summing the contributions of the individual parameters, where a parameter of type long or double contributes two units to the length and a parameter of any other type contributes one unit.

因此看来宿主机是32位还是64位对参数个数没有影响。如果您注意到,该文档以 "units" 的形式说话,其中一个 "unit" 的长度是字长的函数。如果参数个数与word-size成正比,就会存在可移植性问题;您将无法在不同的体系结构上编译相同的 Java 程序(假设至少一种方法在具有较大字长的体系结构上使用了最大数量的参数)。

我从有关此的时事通讯中发现了一个有趣的问题,http://www.javaspecialists.eu/archive/Issue059.html

The per-class or per-interface constant pool is limited to 65535 entries by the 16-bit constant_pool_count field of the ClassFile structure. This acts as an internal limit on the total complexity of a single class or interface. The amount of code per non-native, non-abstract method is limited to 65536 bytes by the sizes of the indices in the exception_table of the Code attribute, in the LineNumberTable attribute, and in the LocalVariableTable attribute.

The greatest number of local variables in the local variables array of a frame created upon invocation of a method is limited to 65535 by the size of the max_locals item of the Code attribute giving the code of the method. Note that values of type long and double are each considered to reserve two local variables and contribute two units toward the max_locals value, so use of local variables of those types further reduces this limit.

The number of fields that may be declared by a class or interface is limited to 65535 by the size of the fields_count item of the ClassFile structure. Note that the value of the fields_count item of the ClassFile structure does not include fields that are inherited from superclasses or superinterfaces.