Reputation: 10003
i need to do something before some static initialization.
i came up with the code below.
is this a sane way to go about it?
thanks
class Needs {
static final int tobeStaticInitialized;
static {
while(!SomethingRequired.isDone())
try {
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
tobeStaticInitialized=42;
}
}
class SomethingRequired {
static boolean isDone() {
return done;
}
static void done() {
System.out.println("doing something required before access.");
done=true;
}
private static boolean done;
}
public class Initialize implements Runnable {
public static void main(String[] arguments) throws InterruptedException {
new Thread(new Initialize()).start();
Thread.sleep(50);
SomethingRequired.done();
}
@Override public void run() {
System.out.println("trying to access someting.");
int x=Needs.tobeStaticInitialized;
System.out.println("got it: "+x);
}
}
Upvotes: 0
Views: 75
Reputation: 718768
I think you are tying to get the value of tobeStaticInitialized
while it is still in the "default initialized" state; i.e. before the static initializer block runs.
Will it work?
I think that the answer is No.
The JLS says this (12.4.1):
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T is a class and an instance of T is created.
A static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
...
In your example, this statement should trigger the class initialization:
int x = Needs.tobeStaticInitialized;
and hence the value assigned to x
should be 42
.
There is a larger question of how you could achieve what you are trying to do. If this was a "green field" problem, then you could try to exploit this "loophole" in the spec:
The fact that initialization code is unrestricted allows examples to be constructed where the value of a class variable can be observed when it still has its initial default value, before its initializing expression is evaluated, but such examples are rare in practice.
The examples that the spec alludes to involve classes with circular dependencies.
The problem is that if you have an existing class you probably can't manufacture the circularity without modifying the class itself. But if you can modify the class, it is better to rewrite its static initialization logic.
If you are really stuck and you can't change the initialization at the source code level, maybe you should consider using a "byte code engineering" hack. Is this "sane"? IMO, No!
Upvotes: 1