代码过长,编译失败

本文探讨了Java中方法代码长度的限制,解释了为何会出现'代码过长'编译错误,以及初始化代码块和数组初始化的相关限制。JVM规范规定方法字节码大小不超过64kb,这在加载class文件时会进行验证。此外,文章还提到了类字段数量、方法参数数量的限制,并讨论了这些限制在实际编程中的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:代码过长,编译失败 — 养恐龙

今天当发版工具人时遇到编译报错「代码过长(code too large)」,把这段说明发到工作群里,瞬间听到周围一片爽朗的笑声……

挺让我惊讶,原来 Java 里的方法大小是有限制的——编译后的字节码大小不能超过 64kb。

JVM 规范 Chapter 4. The class File Formatclass 结构的 method_info (方法信息)里定义了一个 u1 类型1的数组来保存该 Java 方法编译后的数据,这个数组的大小由一个 u2 类型2的变量确定。

1 个 u2 类型的值占 2 byte, 2 byte 就是 16 bit(位),16 bit 所能表示的最大值是 2 的 16 次方——65536。因此一个 u2 类型的变量的最大值就是 65536,所以这个数组也就最多只能保存 65536 byte,即 64kb 的数据。(1 kb = 1024 byte)

这个错误虽然可以在编译期间暴露,但 JVM 并不能保证它加载的 class 文件都是满足要求的,因此在加载 class 文件的验证阶段,还会对该数组的长度进行检查。


除了普通方法外,构造方法、初始化代码块也受到此限制。

初始化代码块为什么也受到此限制呢?我猜测初始化代码块在 JVM 层面还是当作方法来使用的。

同时,如果一个 Java 类里有多个初始化代码块,虽然每个代码块里的代码没有超出此限制,但当它们之和超过该限制时,也会编译报错「代码过长」。我猜测多个初始化代码块在 JVM 层面会被优化成一个方法来使用。

代码块保存在 JVM 的哪块区域?

比如:

public class DayOne{
  {
    System.out.println("哈哈哈哈哈");
    // repeat 4000 times
    System.out.println("哈哈哈哈哈");
  }
  {
    System.out.println("哈哈哈哈哈");
    // repeat 4000 times
    System.out.println("哈哈哈哈哈");
  }
  {
    System.out.println("哈哈哈哈哈");
    // repeat 4000 times
    System.out.println("哈哈哈哈哈");
  }
}

更有趣的是,Java 中数组的大小理论上与 int 的取值范围相关,但实际上可能在初始化数组时,还未达到最大容量便报错「代码过长」:

{
	String[] arr = new String[]{
    "哈哈哈含安安安安哈哈哈含安安安安哈哈哈含安安安安哈哈哈含安安安安",
    //…… repeat 10000 times
    "哈哈哈含安安安安哈哈哈含安安安安哈哈哈含安安安安哈哈哈含安安安安"
	}
}

类似的,JVM 规范 还介绍了「类或接口可以声明的字段数量限制在 65535」「方法参数的数量限制为 255」等情况。:)


  1. 1 byte (字节)的无符号数 ↩︎

  2. 2 byte 的无符号数 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值