135

What is the maximum number of parameters that a method in Java can have and why?

I am using Java 1.8 on a 64-bit Windows system.

All the answers on StackOverflow about this say that the technical limit is 255 parameters without specifying why.

To be precise, 255 for static and 254 for non-static (this will be the 255th in this case) methods.

I thought this could be described in some sort of specification and that there is simply a statically defined maximum number of parameters allowed.

But this was only valid for int and all 4-bytes types. I did some tests with long parameters, and I was only able to declare 127 parameters in that case.

With String parameters, the allowed number I deduced from testing is 255 (it may be because the reference size is 4 bytes in Java?).

But since I am using a 64-bit system, references size should be 8 bytes wide and so with String parameters the maximum allowed number should be 127, similar to long types.

How does this limit is exactly applied?

Does the limit have anything to do with the stack size of the method?

Note: I am not really going to use these many parameters in any method, but this question is only to clarify the exact behavior.

Umberto Raimondi
  • 16,269
  • 7
  • 44
  • 54
userv
  • 2,336
  • 3
  • 26
  • 34
  • 40
    7, if you don't want to go insane with readability. (I know what you're actually asking). – Adam Jun 01 '15 at 19:27
  • 14
    I would argue `<= 4`. Anything more should probably be wrapped up into an object. – Vivin Paliath Jun 01 '15 at 19:30
  • 1
    _i was able to declare only_ What compilation error did you get when you tried with more? – Sotirios Delimanolis Jun 01 '15 at 19:33
  • 4
    Why is this an interesting question? If you're writing a program and you're reaching this limit, then your design is wrong. I don't understand why such a practically useless question gets so many upvotes. – Jesper Jun 01 '15 at 20:55
  • 20
    @Jesper because this questions questions knowledge of JVM specification. This question doesn't ask "How to do this or that ?" instead it questions "Why I need to that ?"... +1 Interesting question Userv – Amit Jun 02 '15 at 04:15
  • 1
    @Sotirios error : too many parameters – userv Jun 02 '15 at 04:38
  • 2
    @amit exactly what I was thinking. The OP just was curious about it. – Evan Carslake Jun 02 '15 at 04:38
  • 1
    I guess that could be useful to know for automatically generating compilable code. – LordOfThePigs Jun 02 '15 at 09:35
  • *"I tried this with long parameters, and I was able to declare only 128 parameters in this case."* - according to the spec, each long is 2 units, and 2 * 128 = 256 which exceeds the limit of 255. Are you sure you managed to declare 128 long parameters? – Alex Humphrey Jun 02 '15 at 11:56
  • @Alex it is 127. I have edited it. Thanks – userv Jun 02 '15 at 12:08
  • @Jesper, I came across this post when I received a SOAP WSDL file that has an object defined with more than 256 members and a warning the Java constructor generated from it would fail because it would have more than the allowable number a parameters. – sdoca Mar 28 '17 at 21:15
  • Note that you can effectively use as many parameters as you want. Collections still are objects and called by reference. You could use a Map or a List to emulate parameters but passing thousands of them in a single argument. – hajef Jun 20 '17 at 18:29
  • @Jesper For a practical example: I want to make a "`print`" method (a shortcut) that both takes a variable number of arguments AND prints arrays and lists nicely. But to differentiate `print(1,2,3)` and `print(new int[]{1,2,3})`, I cannot use `print(Object... args)`, but need to declare methods like `print(Object arg0,Object arg1,Object arg2)` for all possible numbers. So I will put 256 `print` methods into a (horrible looking) class and then one more for 257+ arguments (which actually works with the `Object...` notation). – Fabian Röling Dec 12 '18 at 15:46

3 Answers3

111

That limit is defined in the 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.

Section §4.3.3 gives some additional information:

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.

Your observations were spot on, double word primitives (long/double) need twice the size of usual 4 bytes variables and 4 bytes object instance references.

Regarding the last part of your question related to 64bit systems, the specification defines how many units a parameter contribute, that part of the specification must still be complied with even on a 64bit platform, the 64bit JVM will accomodate 255 instance parameters (like your 255 Strings) regardless of the internal object's pointer size.

Community
  • 1
  • 1
Umberto Raimondi
  • 16,269
  • 7
  • 44
  • 54
  • 10
    I'd add to this answer that on 64 bit architecture the stack is also 64 bit. So, since the limitation on parameter count is stack size bound, 64-bit stack allows storing the same 255 object references. The specific treatment of `long` and `double` regardless of system architecture occurs in many places of the spec and appears to be a remnant of 32-bit era. – Sergei Jun 01 '15 at 19:40
  • I was in the process of editing just that part :) Agreed, the spec must still be respected even on different platforms. – Umberto Raimondi Jun 01 '15 at 19:46
  • This only says something about the method descriptor, but what happens with [varargs](http://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html) in the signature? Can you call it with more parameters then? – Mr Tsjolder Jun 01 '15 at 19:48
  • 1
    Yeah, if the number of parameters was a function of word-size, then that would break portability; you couldn't compile the same Java program successfully on different architectures. – Vivin Paliath Jun 01 '15 at 19:51
  • 3
    Varargs are turned into an *Object* array, can be used only one time in the parameter list and occupy the last position. Considering all this, i'd say that using varargs the number of parameters can be "extended" to 254+Integer.MAX_VALUE (at least for the programmer... parameters are still 255), so using that trick you can have Integer.MAX_VALUE object parameters. – Umberto Raimondi Jun 01 '15 at 19:53
  • 1
    @MrTsjolder Take a look at [this answer](http://stackoverflow.com/questions/18164255/what-is-the-maximum-of-number-of-arguments-for-varargs-in-java) for varargs. – Vivin Paliath Jun 01 '15 at 19:54
  • Correct, check that answer for a much lower limit than my optimistically higher one :) – Umberto Raimondi Jun 01 '15 at 19:55
  • Note that the question asks about the limits of [tag:java], whereas this answer is about the limits of the [tag:jvm]. It would be interesting to know whether a similar restriction exists in Java. Because if the Java spec says that there is no limit, that would mean that Oracle's implementation of Java is not conforming to the spec! (And it would be up to the developers of `javac` to figure out a way to encode Java method parameters as JVM method parameters.) – Jörg W Mittag Jun 02 '15 at 09:03
  • On a quick review of section 8.4.1 of the Java 8 JLS I haven't found anything about the size of a parameter list - neither an explicit upper bound nor an explicit statement that it's unbounded. So any limit imposed or not imposed by the language might be considered as conforming to the spec. – piet.t Jun 02 '15 at 09:13
  • Stupid question: how about varargs,e.g `double...params`. It is a different case, right? – rpax Jun 02 '15 at 09:14
  • JörgWMittag, piet.t, as expected... :/ , the JVM Spec is filled with details that are essential to ensure compatibility, #1 source of information for jvm implementors. – Umberto Raimondi Jun 02 '15 at 09:24
  • On the JVM level, no one cares about how the array for a varargs method has been created. Therefore, only the maximum array length is relevant, which is `Integer.MAX_VALUE-2` or so on Oracle’s JVM. For simple cases, it would also be possible to compile Java source code in a way that works in bytecode, e.g. to fill an array with the same single value, you don’t need one instruction per array entry. You also don’t need extra code for `null` parameters. For non-trivial cases, you will hit the byte code limitations even before trying to fill the temporary varargs array. – Holger Jun 02 '15 at 10:58
  • This limitation reflects on Apollo GraphQL autogenerated classes based on a Database Schema. It won't compile – Paixols Sep 13 '18 at 19:33
11

Section 4.3.3 of the JVM specification has the information you are looking for:

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.

Therefore it appears that whether the host-machine is 32-bit or 64-bit has no effect on the number of parameters. If you notice, the documentation speaks in terms of "units", where the length of one "unit" is a function of the word-size. If the number of parameters directly proportional to word-size, there would be portability issues; you wouldn't be able to compile the same Java program on different architectures (assuming that at least one method used the maximum-number of parameters on the architecture with the larger word-size).

Vivin Paliath
  • 87,975
  • 37
  • 202
  • 284
10

I found an interesting issue from a newsletter about this, 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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Matthew Brzezinski
  • 1,493
  • 3
  • 26
  • 47