Java中的方法可以拥有的最大参数数量是什么?为什么?
我在64位Windows系统上使用Java 1.8。
StackOverflow上关于此的所有答案都说技术限制是255个参数而没有指定原因。
准确地说,255表示静态,254表示非静态(this
将是本例中的第255个)方法。
我认为这可以在某种规范中描述,并且只允许静态定义的最大参数数量。
但这只适用于 int
和所有4字节类型。
我使用long
参数进行了一些测试,在这种情况下我只能声明127个参数。
使用String
参数,我从测试中推导出的允许数字是255(这可能是因为Java中的引用大小是4个字节?)。
但由于我使用的是64位系统,因此引用大小应为8字节宽,因此使用String
参数时,允许的最大数量应为127,类似于long
类型。
这个限制是如何应用的?
该限制是否与方法的堆栈大小有关?
注意:我并不是真的会在任何方法中使用这些参数,但这个问题只是为了澄清确切的行为。
答案 0 :(得分:103)
该限制在JVM Specification:
中定义通过方法描述符(第4.3.3节)的定义,方法参数的数量限制为255 ,其中限制包括 this 中的一个单位实例或接口方法调用的情况。
第§4.3.3节提供了一些其他信息:
方法描述符仅在表示总长度为255或更小的方法参数时才有效,其中该长度包括在实例或接口方法调用的情况下 this 的贡献。
总长度是通过对各个参数的贡献求和来计算的,其中long或double类型的参数对长度贡献两个单位,而任何其他类型的参数贡献一个单位。< / p>
您的观察结果是正确的,双字基元(long
/ double
)需要两倍于通常的4字节变量和4字节对象实例引用的大小。
关于与64位系统相关的问题的最后一部分,规范定义了参数贡献的单位数,规范部分必须仍然符合在64位平台上,64位JVM将容纳255个实例参数(如255 Strings
),无论内部对象的指针大小如何。
答案 1 :(得分:11)
Section 4.3.3包含您要查找的信息:
方法描述符仅在表示总长度为255或更小的方法参数时才有效,其中该长度包括在实例或接口方法调用的情况下对此的贡献。 总长度是通过对各个参数的贡献求和来计算的,其中 类型的参数long或double为长度提供两个单位 和 任何其他类型的参数贡献一个单位。
因此,主机是32位还是64位似乎对参数数量没有影响。如果您注意到,文档会以&#34;单位&#34;表示,其中一个&#34;单位&#34;的长度。是字大小的函数。如果参数的数量与字大小成正比,则会出现可移植性问题;您将无法在不同的体系结构上编译相同的Java程序(假设至少有一种方法使用具有较大字长的体系结构上的最大数量的参数)。
答案 2 :(得分:11)
我在时事通讯中发现了一个有趣的问题,http://www.javaspecialists.eu/archive/Issue059.html
ClassFile结构的16位constant_pool_count字段将每类或每接口常量池限制为65535个条目。这是对单个类或接口的总复杂性的内部限制。 每个非本机非抽象方法的代码量由Code属性的exception_table,LineNumberTable属性和LocalVariableTable属性中的索引大小限制为65536字节。
在调用方法时创建的帧的局部变量数组中最大数量的局部变量被Code35属性的max_locals项的大小限制为65535,该属性给出了方法的代码。 请注意,long和double类型的值都被认为是保留两个局部变量并为max_locals值提供两个单位,因此使用这些类型的局部变量会进一步降低此限制。
类或接口可以声明的字段数量被ClassFile结构的fields_count项的大小限制为65535。请注意,ClassFile结构的fields_count项的值不包括从超类或超接口继承的字段。