Java方法声明中的最大参数数目
Java中一个方法的最大参数数量是多less?为什么?
我在64位Windows系统上使用Java 1.8。
关于这个StackOverflow的所有答案说,技术限制是255个参数,没有指定为什么。
准确地说,255是静态的,254是非静态的( this
将是这种情况下的255)方法。
我认为这可以用某种规范来描述,并且只有一个静态定义的允许的最大参数数量。
但是这只对int
和所有4字节types有效 。 我用long
参数做了一些testing,在这种情况下我只能声明127个参数。
使用String
参数,从testing推导出的允许的数字I是255(这可能是因为参考大小是Java中的4个字节?)。
但是由于我使用的是64位系统,引用大小应该是8字节宽,所以对于String
参数,最大允许数应该是127,类似于long
types。
这个限制如何正确应用?
限制与方法的堆栈大小有什么关系?
注意:我不会用任何方法使用这些参数,但这个问题只是为了澄清确切的行为。
该限制在JVM规范中定义:
通过方法描述符(第4.3.3节)的定义,方法参数的数量被限制为255 ,其中在实例或接口方法调用的情况下,限制包括一个单位。
第§4.3.3节提供了一些额外的信息:
一个方法描述符只有在代表总长度为255或更小的方法参数时才是有效的,其中该长度在实例或接口方法调用的情况下包括对此的贡献。
总长度是通过将各个参数的贡献相加来计算的, 其中long或doubletypes的参数对长度贡献两个单位,而任何其他types的参数贡献一个单位 。
您的观察结果显示,双字原语( long
/ double
)需要两倍于通常4字节variables和4字节对象实例引用的大小 。
关于64位系统相关问题的最后一部分,该规范定义了一个参数有多less个单元 ,即使在64位平台上,该规范的一部分仍然必须符合 ,64位JVM将容纳255个实例参数(如255 Strings
)而不pipe内部对象的指针大小。
JVM规范的第4.3.3节提供了您正在查找的信息:
一个方法描述符只有在代表总长度为255或更小的方法参数时才是有效的,其中该长度在实例或接口方法调用的情况下包括对此的贡献。 总长度是通过将各个参数的贡献相加来计算的,其中 long或doubletypes 的参数对 长度 贡献两个单位 , 而任何其他types 的 参数贡献一个单位 。
因此看起来主机是32位还是64位对参数数量没有影响。 如果您注意到,文档以“单位”来表示,其中一个“单位”的长度是字大小的函数。 如果参数个数与字长成正比,就会出现可移植性问题; 您将无法在不同的体系结构上编译相同的Java程序(假设至less有一种方法在体系结构中使用了最大字数的参数)。
我发现一个有关这个问题的通讯有趣的问题, http://www.javaspecialists.eu/archive/Issue059.html
通过ClassFile结构的16位constant_pool_count字段,每个类或每个接口的常量池被限制为65535个条目。 这对单个类或接口的总体复杂性起到内部限制的作用。 通过Code属性的exception_table,LineNumberTable属性和LocalVariableTable属性中的索引大小,每个非本地非抽象方法的代码量被限制为65536个字节。
调用一个方法时创build的一个框架的局部variables数组中的局部variables的最大数量被限制为65535,这是由给出该方法的代码的Code属性的max_locals项目的大小决定的。 请注意,long和doubletypes的值都被认为是保留了两个局部variables,并且向max_locals值贡献了两个单位,所以使用这些types的局部variables进一步减less了这个限制。
可以由类或接口声明的字段数由ClassFile结构的fields_count项的大小限制为65535。 请注意,ClassFile结构的fields_count项的值不包括从超类或超接口inheritance的字段。