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