Java国际化(i18n)中getContents()方法代码超出65535字节限制的拆分方案咨询
解决ListResourceBundle方法字节码超过65535限制的方案
这个问题我之前处理过——Java虚拟机对单个方法的字节码大小有硬性限制(最大65535字节),10万行的数组直接写在getContents()里肯定会触发这个报错。下面给你几个实用的拆分方案:
方案1:拆分方法,合并数组
把原来的大数组拆分成多个小的私有方法,每个方法返回一部分键值对数组,最后在getContents()里把这些数组合并起来返回。这样每个小方法的字节码都不会超过限制,示例代码如下:
public class ListNames extends ListResourceBundle implements ListNamesInterface { @Override protected Object[][] getContents() { // 拆分多个部分数组 Object[][] partA = getPartA(); Object[][] partB = getPartB(); Object[][] partC = getPartC(); Object[][] partD = getPartD(); // 计算总长度并初始化结果数组 int totalLength = partA.length + partB.length + partC.length + partD.length; Object[][] result = new Object[totalLength][]; // 复制各部分到结果数组 System.arraycopy(partA, 0, result, 0, partA.length); System.arraycopy(partB, 0, result, partA.length, partB.length); System.arraycopy(partC, 0, result, partA.length + partB.length, partC.length); System.arraycopy(partD, 0, result, partA.length + partB.length + partC.length, partD.length); return result; } // 每个私有方法存放一部分键值对,控制每个方法的行数(比如2-3万行) private Object[][] getPartA() { return new Object[][] { {"ALPHA", "Alpha"}, {"BETA", "Beta"}, // ... 这里放2-3万条数据 }; } private Object[][] getPartB() { return new Object[][] { // ... 下一批2-3万条数据 }; } // 继续添加更多拆分的方法... }
注意每个拆分的方法不要放太多数据,大概2-3万条左右就能保证字节码不超限制,可以根据实际每条数据的长度调整。
方案2:迁移到外部.properties文件(更推荐)
把所有键值对迁移到标准的国际化属性文件中,完全避开Java方法字节码的限制,这也是Java国际化的标准实践。
比如创建ListNames_en_US.properties文件(根据你的语言环境命名),内容格式如下:
ALPHA=Alpha BETA=Beta # ... 10万条键值对依次排列
然后不需要再继承ListResourceBundle,直接通过ResourceBundle加载即可:
ResourceBundle bundle = ResourceBundle.getBundle("ListNames", Locale.US); String alphaValue = bundle.getString("ALPHA");
这个方案的优势很明显:维护更方便(不需要修改Java代码重新编译),文件体积更小,完全没有字节码限制问题,而且符合Java国际化的规范。
方案3:静态初始化块构建数组
如果一定要保留Java类的形式,也可以用静态初始化块分批次构建数组:
public class ListNames extends ListResourceBundle implements ListNamesInterface { private static Object[][] contents; static { // 初始化总长度 contents = new Object[100000][]; // 分批次添加元素 addBatch1(); addBatch2(); // ... 更多批次 } private static void addBatch1() { contents[0] = new Object[]{"ALPHA", "Alpha"}; contents[1] = new Object[]{"BETA", "Beta"}; // ... 添加2-3万条 } private static void addBatch2() { // 继续添加下一批元素,注意索引不要越界 contents[20000] = new Object[]{"GAMMA", "Gamma"}; // ... } @Override protected Object[][] getContents() { return contents; } }
这个方案的代码相对繁琐,不如前两个方案直观,除非有特殊需求,否则优先考虑方案1或2。
内容的提问来源于stack exchange,提问作者Luca95
相关产品推荐
相关产品推荐

