Say I have a base class A
(with a virtual method called normalInit()
), and 300 subclasses: A1, A2, A3, ...
Each of these subclasses have a staticInit()
static method, plus a normalInit()
override. (Please don't ask why; this is in a production software, already given, can't change the design for better reuse. Actually, those subclasses are generated by a code generator, but this is irrelevant now.)
Depending on the different executions of the application, a (small) subset of A1, A2, A3, ...
needs to be initialized. In other words, there are some data that all instances of a particular Ai
share or access commonly. Obviously, it is reasonable to define and treat these entities as static
members/methods (as they are shared by all instances of an Ai
).
So how to initialize the statics (and call the static methods) of this subset?
To be brief, it's not a solution to static-initialize all Ai
subclasses, because only a small subset will be required (would be a waste of memory). The static
behavior in Java apparently gives a solution to this: the static
initializers of a class are initialized when a class is accessed for the first time (I disregard some special cases here, e.g. compiler inline of pritimive final statics, as in that case, technically there is no class access, just on source code level).
The problem is, I need deterministic (actually at-predefined-time) static initialization, because their static
behavior also accesses the current static (global) state of the application. So static
initializers are not an option, I need static
methods, to call them explicitly at the appropriate place.
In the application in question, this must be done when instances of various Ai
classes are accessed via iterating through an ArrayList<A>
, where A
is the superclass.
for (int i = 0; i < list.size(); ++i) {
list[i].normalInit(args); // normalInit() is an instance method
}
This list consists of Ai
instances (e.g. 950 instances of A1
, 1750 instances of A2
, etc., in an unsorted, "random" order).
In other words, I don't have access to concrete class names (so I can't just call A4.staticInit()
), because I don't know which Ai
has instances in the list. Note that I know statics are bound at compile time and I do know that polymorphism is not possible here, so I'm not asking how to call the static methods from the above loop! The concretely called instance (and thus its Class
) is decided at runtime, due to dynamic dispatch, when normalInit()
is called.
An apparent solution is to call the concrete class' staticInit()
method from the normalInit()
override:
public class A2 {
@Override
public void normalInit(int[] args) {
// ...
staticInit();
}
private static void staticInit() {
if (!sStaticInitialized) {
sStaticInitialized = true;
...
}
}
}
For this, the code generator templates that generate the Ai
subclasses must be modified.
But this (and the above code) doesn't look like a nice solution. I understand if the overall app design is somewhat flawed, but even if that's your viewpoint, I would grateful if such claims are augmented with additional (independent) constructive advice. Is there a nicer solution/idiom to the above issue?