Luk*_*der 6 java compiler-construction compiler-errors static-initialization
我有一个类,它持有大量生成的常量:
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(...);
}
Run Code Online (Sandbox Code Playgroud)
当生成的常量数非常高时,这会导致静态初始化程序大于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(...);
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是我不能再将常量声明为final,因为它们现在不再直接在静态初始化器中初始化.
我的问题是,如何以一种我仍然可以生成static final常量的方式规避编译器/ JVM限制?
一种选择是使用继承 - 有一系列类Constants1,Constants2...,ConstantsN它们都定义了常量,然后让每一个继承自前一个.最后一个类Constants可以直接从它们的最后一个继承.这也可以让你标记一切final.
出于好奇,你是如何最终得到一个如此大的文件,以至于你无法将初始化代码放入64KB的限制中?
希望这可以帮助!
我最终寻求了一个涉及嵌套类的解决方案。这是用户Loadmaster在对此答案的评论中建议的。嵌套类有两个优点:
private它们允许通过嵌套类向外界隐藏这些解决方法的实现细节final但与templatetypedef 的解决方案相比,它们也有一个缺点:
然而,目前这似乎是最合适的解决方案:
public class Constants {
public static XXX KEY1 = Constants1.KEY1;
public static XXX KEY2 = Constants1.KEY2;
public static XXX KEY3 = Constants1.KEY3;
// ...
public static XXX KEY2000 = Constants2.KEY2000;
// Nested class holding 1000 constants
private static class Constants1 extends SomeBaseClass {
KEY1 = init(...);
KEY2 = init(...);
KEY3 = init(...);
// ...
}
// Nested class holding the next 1000 constants
private static class Constants2 extends SomeBaseClass {
// ...
KEY2000 = init(...);
}
// Keep generating nested classes for more constants...
private static class Constants3 ... {}
}
Run Code Online (Sandbox Code Playgroud)