【发布时间】:2012-05-31 21:47:20
【问题描述】:
我有一个类包含大量生成的常量,例如:
public class Constants extends SomeBaseClass {
// init() is defined in some base class...
public static final XXX KEY1 = init(...);
public static final XXX KEY2 = init(...);
public static final XXX KEY3 = init(...);
// ...
public static final XXX KEY2000 = init(...);
}
当生成的常量数量非常多时,这会导致静态初始化器大于 Java 方法大小的上限(即 > 64kb),从而导致编译器错误。一种解决方案是为可以保证生成少于 64kb 字节码的块创建多个“块初始化方法”,以便它们适合一种方法:
public class Constants extends SomeBaseClass {
public static XXX KEY1;
public static XXX KEY2;
public static XXX KEY3;
// ...
public static XXX KEY2000;
static {
initialise0001To1000();
initialise1001To2000();
}
private static void initialise0001To1000() {
KEY1 = init(...);
KEY2 = init(...);
KEY3 = init(...);
// ...
}
private static void initialise1001To2000() {
// ...
KEY2000 = init(...);
}
}
这样做的缺点是我不能再将常量声明为final,因为它们现在不再直接在静态初始化器中初始化。
我的问题是,我怎样才能绕过编译器/JVM 的限制,而我仍然可以生成 static final 常量?
【问题讨论】:
-
你是怎么遇到这个问题的?此代码是从另一个文件自动生成的吗?
-
@templatetypedef:这是jOOQ 的源代码生成器中的一个实际错误。它从数据库生成主键、唯一键和外键作为常量对象。看来 2000 个键对于 jOOQ 来说太多了:groups.google.com/d/topic/jooq-user/2g96fI1Yrj8/discussion
-
您可以为此使用“虚拟”继承层吗?有一个带有一些非公共名称的基类,其中包含 1,000 个常量,并有一个静态初始化程序设置它们。然后一个派生类增加了 1000 个,子派生类又增加了 1000 个,等等?除了派生程序集中的其他类之外,只有派生度最高的类才会用于任何目的。
-
@supercat:我想你可以。限制实际上是由类标头中的各种 16 位(双字)标头字段强加的。所以,我猜这可以通过继承来规避......不过,您必须在字节码中验证这一点(例如,使用
javap)
标签: java compiler-construction compiler-errors static-initialization