I have a class holding a large a mount of generated constants as such:
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(...);
}
When the number of generated constants is very high, this results in a static initialiser that is larger than the upper limit for Java method sizes (i.e. > 64kb), resulting in a compiler error. One solution is to create several "block initialisation methods" for blocks that can be guaranteed to produce less than 64kb of byte-code, such that they fit into a method:
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(...);
}
}
The drawback of this is that I can no longer declare the constants as final
, because they are now no longer initialised directly in the static initialiser.
My question is, how can I circumvent that compiler / JVM limitation in a way that I can still generate static final
constants?
I finally went for a solution involving nested classes. This was suggested in a comment to this answer here by user Loadmaster. Nested classes have two advantages:
private
nested classesfinal
But they also have a disadvantage compared to templatetypedef's solution:
Right now, however, this seems to be the most suitable solution:
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 ... {}
}