Re: Puzzling class field initialization order

Brian Maso <[email protected]>
Newsgroups gmane.comp.windows.devel.java.advanced
Message-ID <ADVANCED-JAVA%[email protected]>
That's a wierd one indeed. Looks like you hit a 
strange corner-case of the VM spec: see section 2.17.4:

"...
"Before a class or interface is initialized, its 
direct superclass must be initialized, but 
interfaces implemented by the class need not be 
initialized. Similarly, superinterfaces of an 
interface need not be initialized.
"..."

The section further explains these events 
beforewhich a class must be initialized:
* T is a class and an instance of T is created
* T is a class and a static method of T is invoked
* A nonconstant field of [class or interface] T 
is used or assigned. ("Nonconstant" == "final 
static", which is special and is treated 
differently if it is primitively typed or of type String or Class.)

So based on that, it seems the 1.5.0 VM you are 
using is not breaking the initialization ordering 
rules -- although it certainly is surprising that 
the interface initialization is delayed. It's a 
pretty wild case though with the superclass and 
superinterface static field actually dependant on 
the subclass/implementing class static fields. 
How did you even think to come up with it?

Brian Maso

At 06:22 AM 9/6/2007, you wrote:
>Hi folks,
>
>I observed an interesting behaviour in initialization of static fields,
>and am unable to understand it. Can anyone help? Here's the code distilled
>to absolute minimum demonstrating the problem, in four classes:
>
>S.java:
>=======
>class S {
>     static final C IMPL = C.INSTANCE;
>}
>
>I.java:
>=======
>interface I {
>     static final C IMPL = C.INSTANCE;
>}
>
>C.java:
>=======
>class C extends S implements I {
>     static final C INSTANCE = new C();
>}
>
>X.java:
>=======
>public class X {
>     public static void main(String[] args) {
>         C c = new C();
>         System.out.println(S.IMPL);
>         System.out.println(I.IMPL);
>     }
>}
>
>Running X prints null for S.IMPL, as expected, since S.IMPL was
>initialized before C.INSTANCE when C was loaded. That's perfectly
>understandable.
>
>*However* it prints a non-null instance for I.IMPL, i.e. "C@2e7263"! Now,
>anyone care to explain why isn't I.IMPL null as well? It is likely
>something related to a difference in loading a superclass vs. loading a
>superinterface, but if anyone has a definitive explanation (a pointer to
>the relevant JVM spec section will suffice :-)), I'd appreciate that.
>
>BTW, Java runtime version is:
>
>java version "1.5.0_07"
>Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-164)
>Java HotSpot(TM) Client VM (build 1.5.0_07-87, mixed mode, sharing)
>
>Thanks,
>   Attila.
>
>--
>home: http://www.szegedi.org
>weblog: http://constc.blogspot.com
>
>===================================
>This list is hosted by DevelopMentor®  http://www.develop.com
>
>View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentor®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.