Re: Puzzling class field initialization order
Attila Szegedi <[email protected]>
| Newsgroups | gmane.comp.windows.devel.java.advanced |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 06 Sep 2007 16:07:35 +0200, Brian Maso <[email protected]> wrote: > > 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? Distilling a real-world example, of course :-) Namely, FreeMarker has an interface named "ObjectWrapper", which has a static final field named BEANS_WRAPPER that's initialized to static final BeansWrapper.DEFAULT_INSTANCE, which in turn is initialized to "new BeansWrapper()". And BeansWrapper implements ObjectWrapper. It's actually something that FindBugs pinpointed as a potential problem, so I decided to poke around. Actually, we'll probably end up removing the whole bunch of those static fields for unrelated reasons (namely, because of the Singletons Are Evil rule). Attila. > > 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. =================================== This list is hosted by DevelopMentor® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com