Java编译错误 code too large

thinking man

背景

通常公司里做国际化翻译管理的时候都会搭建一个Web应用去编辑管理翻译内容,最后在使用程序生成相应的语言包,我们也一样这么做。原来是生成JavaScript语言包,现在也要使用同样的数据生成Java语言包给Java项目使用。这样做有个好处就是所有的翻译资源统一管理,然后通过读取统一的数据源生成相应的语言包给开发使用,确保它们的翻译内容无论在那个程序语言里都是通用的。

【爆款云服务器限时促销】
阿里云云服务器ECS实例2核2G,新人专享渠道特惠价只要82元!特惠热卖中。 点击立即购买

想法

所有的翻译内容最终会生成一个i18n.json文件,然后JavaScript和Java去解析这个json文件即可,所以i18n.json相当于一个翻译内容的文件数据库,它的内容结果如下:

i18n.json

{
  "NAME": {
    "zh": "名字",
    "en": "Name"
  },
  "CITY": {
    "zh": "城市",
    "en": "City"
  },
  "AGE": {
    "zh": "年龄",
    "en": "Age"
  }
}

这个json文件里定义了一堆唯一的Key,每个Key里分别包含zhen翻译文本,于是我想出了在Java里可以定义一个枚举类型包含所有的Key值,大概如下:

public enum Keys {
  AGE,
  NAME,
  CITY;
}

然后我假设暴露一个API给用户通过Key获取翻译内容

public String get(Keys key) {
  ...
}

让用户使用枚举类型获取翻译文本有以下好处:

  • 减少运行时的错误,如果输入的Key不在枚举值里编译会错误
  • 通过IDE的自动提示可以很轻松找到Key值

如果不使用枚举值,可能定义的方法如下

public String get(String key) {
  ...
}

那么在开发者使用时可能它要频繁切换到国际化平台的Web应用上去找到相应的Key值,然后粘贴过来,并且Key值要确保复制完整。

于是我通过Python脚本读取i18n.json文件,并生成了一个i18n.java文件,里边有一个Keys的枚举值,它包含了所有从Key值,我迫不及待的想马上去使用它。

现实残酷

我通过mvn deploy的失败输出中捕获了关键字

BUILD FAILED: code too large

What? 这是什么鬼?

通过查阅才知道,如果你的单个方法超过了64KB,那么JVM会引发这个编译错误,并终止编译。

64KB是个什么概念?

我们来算一算,因为我的Java源文件是UTF-8字符集,我们就以它来计算。 在UTF-8字符集里,一个英文字符占一个字节,1KB等于1024字节,就相当于1024个英文字符

64KB = 1024B * 64 = 65536 约6.5万个字符

实际上,i18n.json文件里大约有1万个Key,每个Key的长度平均10个字符,我们算一下实际占用

10B * 10000 = 约等于97KB

好吧,确实比最高限制64KB超出了大概30KB。没办法,我只好放弃使用enum来做Key的传参,只能使用String来替代它。

实际上,64KB的限制相当于6.5万个字符的限制在正常编程开发是绝对够用的,你要真的在一个方法里敲打的字符超过上万个我都觉得很恐怖了,以及很不好维护了,一般只有通过程序生成的Java源文件可能会不小心突破64KB这个JVM的限制。

分享

TITLE: Java编译错误 code too large

LINK: https://www.qttc.net/508-java-compile-error-code-too-large.html

NOTE: 原创内容,转载请注明出自琼台博客