• 周四. 10 月 3rd, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

How many parameters can a Java method use?

King Wang

1 月 3, 2022

I gave it to me recently fork Project QuickTheories Added an interface :

@FunctionalInterface
public interface QuadFunction<A, B, C, D, E> {
E apply(A a, B b, C c, D d);
}

This makes me wonder how many type parameters a method can have ? as far as I am concerned ,Java This is not mentioned in the language specification of .1

The definition of this threshold in implementation , I have two guesses :

  1. The compiler forces a predictable threshold , for example 255 perhaps 65535.
  2. Because of the implementation details , The compiler’s exception handling imposes unexpected restrictions .

I don’t want to pass through my weak C++ Skills to test source code , So I decided to test the compiler directly 2. I wrote one Python Script , Find a minimum value that triggers an error by dichotomy . For the complete code, please refer to the link Github Repo.

The most direct way is to generate methods . Fortunately, , We don’t have to use any existing type parameters , Just follow <A,B,C..> To generate :

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("}")

The code that runs this dichotomy will have the following output :

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

This mistake is a little confusing , But it’s understandable when you look at it later . The class file generated by the compiler contains multiple strings , Include the method signature for each method . These strings are stored in the constant pool , And the content of constant pool is Maximum 65535 The limit on the number of bytes , This is JVM As defined by .

therefore , My previous conjectures were not entirely correct . The maximum number of type parameters is an unexpected value , Instead of a definite value . however , The implementation of the compiler itself is not the cause of the error 3. contrary , yes JVM Class file format requirements limit the number of type parameters that can be used . Actually JVM Nothing about generics themselves .

It also means that the maximum number of type parameters depends on the method code you write 4. I tried to use a different encoding scheme for type parameters ( In the previous link write_type_compact), Use all legal ASCII character . This implementation is a little cumbersome , Because the characters 0-9 It’s legal. , But it can’t be used as the first letter of an identifier , also Java Keywords cannot be used as type parameters . I will only if and do Replace with equal length UTF-8 character . Using this more compact coding scheme, the number of type parameters is changed from 2776 Promoted to 3123.

There are still some inconveniences , for example _A It’s a legal Java identifier , however _ No . My code is not using _ As the first subtitle , The highest generation 3392 individual 2 Type parameter of byte . So I don’t think about it _ As an initial .

Another trick

By decompiling class files , I observed 65536 Most of the characters are not my generated type parameters , It’s a repeating string Ljava/lang/Object;. This is because the type parameter does not contain additional information , So class files treat it as Object Inheritance , And put them into the method signature . I optimize this problem by modifying my generator .

The key code of the loop is changed to :

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

Except for an example , All type parameters inherit from java/lang/Object Instead of inheritance A. This change increases the number of type parameters to 9851 individual .

The number of type parameters has increased a lot , And the coding method I use can continue to improve . For example, use non ASCII unicode identifier , But I’m quite satisfied with the effect now .

None of this matters

In practice, it is unlikely to reach the above limit . Code generation may reach some limits of the language or compiler , Even if it’s rare to have hundreds of type parameters generated , That’s still a long way from the thousands of restrictions .

For all that , If I were a rule maker , I will not allow any class or method to use more than 255 Type parameters . Even if it only affects one millionth of the program , It would be better to have clear limits .

  1. §4.4, §8.1.2, §9.1.2, §8.4.4, §8.8.4 These chapters are all about the type parameters of methods or classes , But it doesn’t indicate how many type parameters are allowed .
  2. When I write this paragraph , I remember. Hotspot yes C++ Written ,javac yes Java Written . Even so, I still choose to do code experiments , Instead of reading the code . Reading other people’s code is a pain
  3. Spaces after commas do not affect , Because the compiler normalizes its output .
  4. It also means which one to use with me JVM irrelevant . For completeness , I am here Fedora 29 It has been used. 1.8.0_191-b13 Version of OpenJdk.

The author of this article :justinblank, translate :1 Way Link to the original text :https://justinblank.com/experiments/howmanytypeparameterscanajavamethodhave.html First translation :http://blog.didispace.com/howmanytypeparameterscanajavamethodhave/

This article has spring4all The technical translation team finished , More foreign frontier knowledge and good articles on dry goods , Welcome to the official account : Back end interviews .

发表回复