A Java method parameter types can have how many? The coder made a curious experiment

In the JVM, a Java method, up to the number of parameters defined it? This is a very silly questions, even if we can define ten thousand, one hundred thousand, who would really go to do it. But as a coder, the most important is not curiosity you, no curiosity, and what is the difference between a salted fish have it? The author is such a coder is full of curiosity.

Selected from heart compile justinblank, the machines involved: Li Zhiwei, Zhang Qian.

I recently gave my QuickTheories branch add an interface:

@FunctionalInterfacepublic interface QuadFunction<A, B, C, D, E> {    E apply(A a, B b, C c, D d);}复制代码

Let me curious is that this method can have the number of type parameters. So far, I dare say, Java language specification does not talk about this issue.

What may be the achievement of a defined limit, I have two guesses:

  1. The compiler sets a predictable limit, such as 255 or 65535.

  2. Emergency behavior of the compiler is provided unexpected limitations due to implementation details (the same stack overflow or unpredictable / things that are not related).

I do not want to test my pathetic C ++ skills on the source code, so I decided to test only the compiler does. I wrote a Python script that uses a binary search to find the least fault caused by the type parameter. Complete script repo on Github ( github.com/hyperpape/j... in).

Script Address: github.com/hyperpape/j...

Generation method is very simple. Fortunately, we do not have to use any type of parameter by issuing them with <a, b, c ...> forms:

def write_type_plain(count):    with open('Test.java', 'w') as f:        f.write("public class Test {\n")        f.write("public <")        for i in range(count):            if (i > 0):                f.write(", ")            f.write("A" + str(i + 1))        f.write("> void testMethod() {}")        f.write("}")复制代码

Run Binary search can get the following output:

>>> error: UTF8 representation for string "<A1:Ljava/lang/Objec..." is too long for the constant pool>>> largest type: 2776复制代码

This error is a little vague, but hindsight is predictable. Compiler generates class files comprising a plurality of strings, each method comprising the class signature. These strings are stored in the constant pool entry, the maximum constant pool of 65535 bytes, which is limited by the JVM specification.

So, as I guess not entirely correct. The maximum number of parameters is a type of emergent characteristics (emergent property), rather than a clear-cut decision. However, the implementation is not the compiler itself caused the error.

Instead, JVM class file format can limit the number of parameter types represented in the class file. This is true, despite the generic JVM for nothing. This also means that the maximum number of type parameters depends entirely on how to write method.

I tried a new type of encoding parameters of the method (previously write_Type_Compact linked file), using the full legal ASCII characters (AZ, az, $, and _). The realization of a little too complicated, because you can use the characters 0 through 9, but not the initial character of an identifier, because Java keywords can not appear as the type parameter. I just replaced the short word "if" and "do" with equal length UTF-8 characters. More compact coding parameters from the number 2776 3123 is increased.

Is inconvenient, _A is a legitimate Java identifiers, but _ is not. Thankfully, my coding is generated in the 3392 2-byte type parameters _ without using the initial situation, so I think there is no need for bookkeeping in order to make the initial character _.

One more tips

Decompression class documents show that most are not my type parameters generated 65,536 characters, but the substring repeated instances Ljava / lang / object of. Since no information on the type of parameters, so the class files show that extend the object and encode it in the method signature. I modified the generator to solve this problem.

The key part of the cycle is:

s = type_var(i)f.write(s)if (s != 'A'):    f.write(" extends A")复制代码

Type parameter in all instances but one example java / Lang / Object have been replaced by A. After making this change, compiled method has a type parameter of 9851.

Due to the number of parameters increased a lot, so I use the code definitely needs to be adjusted. Use a necessary condition for non-ASCII Unicode identifier may be completely efficient, but simply pointed out that this can be done I am very satisfied.

These are not important

Hard to imagine someone would reach this limit. Code Generation sometimes to the limit language or compiler, but even if the generated code does not seem likely to use hundreds of types of parameters.

Still, if I were the rule makers, I would consider explicitly prohibit any class or method has more than 255 types of parameters. Clear limits seems to be better, even if it only affects one in a million procedures.

Original link: justinblank.com/experiments...


Guess you like

Origin juejin.im/post/5d0067c1f265da1bcf5dd3f1