“Code too large” Compilation Error in Java – “代码太大”在Java中编译错误

最后修改: 2021年 7月 4日

中文/混合/英文(键盘快捷键:t)

1. Overview 

1.概述

When a Java method exceeds 65535 bytes, we get the compilation error, “code too large”. In this article, we’ll discuss why this error occurs and how to fix it.

当一个Java方法超过65535字节时,我们会得到编译错误,”代码太大”。在这篇文章中,我们将讨论为什么会出现这个错误以及如何解决这个问题。

2. JVM Constraints

2.JVM的约束

The Code_attribute is a table of variable length in the method_info structure of JVM specifications. This structure contains the JVM instructions for a method, which can be a regular method or an initialization method for an instance, class, or interface:

Code_attribute是JVM规范的method_info结构中的一个可变长度的表格。这个结构包含了JVM对一个方法的说明,这个方法可以是一个常规方法,也可以是一个实例、类或接口的初始化方法。

Code_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 max_stack;
    u2 max_locals;
    u4 code_length;
    u1 code[code_length];
    u2 exception_table_length;
    {   
        u2 start_pc;
        u2 end_pc;
        u2 handler_pc;
        u2 catch_type;
    }
    exception_table[exception_table_length];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}

The attribute code_length specifies the length of the code in a method:

属性code_length规定了方法中代码的长度。

code_length
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.

As can be seen above, JVM specifications state that the code length of a method has to be less than 65536 bytes, so this implies that the size of a method can’t exceed 65535 bytes.

从上面可以看出,JVM规范规定,一个方法的代码长度必须小于65536字节,所以这意味着一个方法的大小不能超过65535字节。

3. Why the Problem Occurs

3.问题发生的原因

Now that we know the size limit for methods, let’s looks at the situations that can result in such large methods:

现在我们知道了方法的大小限制,让我们来看看哪些情况会导致这么大的方法。

  • Code Generators: Most large methods are a result of using some code generator like ANTLR parser
  • Initialization methods: GUI initializations can add lots of details like layouts, event listeners, and many more, all in one method
  • JSP Pages: Contains all the code in one single method of the class
  • Code Instrumentation: Adds bytecode to compiled classes at runtime
  • Array Initializers: Methods initializing very large arrays as shown below:
String[][] largeStringArray = new String[][] {
    { "java", "code", "exceeded", "65355", "bytes" },
    { "alpha", "beta", "gamma", "delta", "epsilon" },
    { "one", "two", "three", "four", "five" }, 
    { "uno", "dos", "tres", "cuatro", "cinco" }, 
        
    //More values
};

4. How to Fix the Error

4.如何修复错误

As we’ve noted, the root cause of the error is a method exceeding the threshold of 65535 bytes. So, refactoring the erring method into several smaller methods will fix the problem for us.

正如我们已经注意到的,错误的根本原因是一个方法超过了65535字节的阈值。因此,将出错的方法重构为几个较小的方法将为我们解决这个问题。

In the case of array initializations, we can either split the arrays or load from a file. We can also use static initializers. Even when we’re using code generators, we can still refactor the code. And in the case of a large JSP file, we can use the jsp:include directive and break it into smaller units.

在数组初始化的情况下,我们可以分割数组或从文件中加载。我们还可以使用静态初始化器。即使我们使用代码生成器,我们仍然可以重构代码。而在大型JSP文件的情况下,我们可以使用jsp:include指令,将其分解成更小的单元。

The above issues are relatively easy to handle, but things get complicated when we get a “code too large” error after adding instrumentation to the code. In case we own the code, we can still refactor the method. But when we get this error from a third-party library, we are in a fix. By reducing the instrumentation level, we might be able to fix the problem.

上述问题相对容易处理,但当我们在代码中添加仪器后,出现 “代码太大 “的错误时,事情就变得复杂了。在我们拥有代码的情况下,我们仍然可以重构该方法。但是当我们从第三方库中得到这个错误时,我们就陷入了困境。通过降低仪器化水平,我们也许能解决这个问题。

5. Conclusion

5.结论

In this article, we’ve discussed the causes and potential solutions to the “code too large” error. We can always refer to the Code_Attributes section of the JVM Specifications to find more details about this constraint.

在这篇文章中,我们已经讨论了 “代码过大 “错误的原因和潜在的解决方案。我们可以随时参考JVM规范中的Code_Attributes部分,以找到有关这一约束的更多细节。