Static blocks don't run when class loaded under jdk 1.5
I'm seeing a new behavior regarding when static code blocks run in jdk 1.5.
In earlier VM's, the static block in the following code would execute as soon as I called MyClass.class.getName().
I never had to actually call a method on the class.
MyClass class {
static String myStaticString;
// static code block
static {
myStaticString = "hello";
}
static init() { //do nothing }
}
Under JDK 1.5, I would now have to call MyClass.init() in order to get the static block to run. This is very troublesome for the many Abstract Factory/Singleton classes I use that are dynamically instantiated at runtime. Is this a bug, or is there an recommended workaround?
Thanks,
Dan
[758 byte] By [
bhamail] at [2007-9-30 18:25:04]

> Is this a bug, or is there an recommended
> workaround?
Did you check the bug database?
There isn't anything explicit in your code that suggests to me that it must be a bug.
From the JVM spec for 12.4.1....
http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#57946
Initialization of a class consists of executing its static initializers and the initializers for static fields declared in the class. Initialization of an interface consists of executing the initializers for fields declared in the interface.
Before a class is initialized, its direct superclass must be initialized, but interfaces implemented by the class need not be initialized. Similarly, the superinterfaces of an interface need not be initialized before the interface is initialized.
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.
- T is a class and 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 reference to the field is not a compile-time constant (?5.28). References to compile-time constants must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization.
...
Given that 'class' is defined as literal and not as any of the above, it is possible that the previous VMs are the ones with the bug.
However the class literal is not mentioned in the compile time constants either (although that could be a documentation bug.)
I've just come across the same problem whilst using the jakarta commons Enum class under JDK1.5; previously it was sufficient just to reference the class literal in code in order for the class to be loaded, now that no longer applies.
Using class.forName does workaround the problem, but in order to continue using the class literal the following (ugly) code now needs to be used:
Class.forName(MyClass.class.getName())
where previously
MyClass.class
would have been sufficient.
Regardless of what the spec. may or may not say, this is a fairly subtle change that could have huge implications for some developers' code.
>
> Regardless of what the spec. may or may not say, this
> is a fairly subtle change that could have huge
> implications for some developers' code.
>
Yes. But so was the enforcement of importing classses in the default name space when 1.3 came out.