Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2005

Tip: Looking for answers? Try searching our database.

mysterious static

Thread view: 
Timo Nentwig - 13 Jun 2005 20:22 GMT
Hi!

I'm somewhat confused:

class Foo
{
   private static final ConditionalPropertiesReader PROPERTIES =
ConditionalPropertiesReader.getInstance();
   private static final String defaultCacheStrategy =
PROPERTIES.getProperty( "jcms.cache.strategy" );

   static
   {
       System.out.println("1 static{}"+defaultCacheStrategy);
   }
...
   public static IJCMSCacheStrategy getDefaultCacheStrategy()
   {
      System.out.println("2 getDefaultCacheStrategy()
"+defaultCacheStrategy);

       return JCMSCacheStrategy.Factory.make( defaultCacheStrategy != null
                                              ? defaultCacheStrategy
                                              :
JCMSCacheStrategy.Factory.CACHESTRATEGY_DEFAULT );
   }          
}

This prints:
2 getDefaultCacheStrategy() null
1 static{} myvalue

Why is that?? If I create an instance of the class prior to calling the
method defaultCacheStrategy in getDefaultCacheStrategy() *does* have the
supposed value. And why is 2 printed first??

Can somebody explain?
Timo Nentwig - 13 Jun 2005 20:53 GMT
> This prints:

If I call Foo.getDefaultCacheStrategy() from another class, of course :)
Chris Uppal - 14 Jun 2005 09:13 GMT
> This prints:
> 2 getDefaultCacheStrategy() null
> 1 static{} myvalue

Unless I'm mis-reading your code, it /shouldn't/ do that.  The static
initialisation should have completed before the static method is entered.
Possibly there's something wrong with your real code that doesn't appear in the
snippet you posted; can you create a complete self-contained example ?

   -- chris
John C. Bollinger - 14 Jun 2005 14:56 GMT
>>This prints:
>>2 getDefaultCacheStrategy() null
[quoted text clipped - 4 lines]
> Possibly there's something wrong with your real code that doesn't appear in the
> snippet you posted; can you create a complete self-contained example ?

I agree that the posted code does not explain the observed behavior, but
I have a guess as to how it's happening.  Class initializers -- the
combination of static variable initialization expressions and static
initializer blocks -- are executed at runtime in the order they appear
in the class' code.  My bet would be that the getDefaultCacheStrategy()
method is invoked within the scope of some method call in one of the
initializers preceding the static initializer block shown.  Because the
class is at that point already in the process of initialization, the
method call proceeds without attempting to start a new initialization,
and the unexpected execution order and default value of
defaultCacheStrategy are observed.  This would be akin to a superclass
constructor invoking a virtual method, and thereby exposing a subclass'
instance variable before it has been initialized by the subclass
constructor.

Schematic sequence:

() class Foo is uninitialized at the beginning of the sequence

() Foo.getDefaultCacheStrategy() is invoked

() the VM loads class Foo, and begins initializing it

() static member baz is initialized by invoking (hypothetical) static
method Foo.getCache()

() Foo.getCache() invokes Foo.getDefaultCacheStrategy(), which prints
the observed message containing the default value for the
defaultCacheStrategy variable

() static member defaultCacheStrategy is initialized via its initializer

() the VM runs the static initializer block, which prints the second
message (numbered 1) which includes the initialized value of
defaultCacheStrategy

() initialization of Foo is complete, execution of
Foo.getDefaultCacheStrategy() begins (for the second time)

() Another message numbered 2 is printed (not reported by the OP)

That's the only thing I can think of.  A class method cannot ever be
invoked before its class is initialized, but it can be invoked *while*
its class is being initialized, in which case it will see a partially
initialized class.

Signature

John Bollinger
jobollin@indiana.edu

Timo Nentwig - 14 Jun 2005 18:25 GMT
>> This prints:
>> 2 getDefaultCacheStrategy() null
>> 1 static{} myvalue
>
> Unless I'm mis-reading your code, it /shouldn't/ do that.  The static

Yes, I found the bug today:
       
class Foo
{
   // the bug:
   private static final DEFAULT_INSTANCE = new Foo();

   private static final ConditionalPropertiesReader PROPERTIES =
ConditionalPropertiesReader.getInstance();
   private static final String defaultCacheStrategy =
PROPERTIES.getProperty( "jcms.cache.strategy" );
...

   // I have to put the singleton stuff here
   // as it depends on the lines above
}
Chris Uppal - 15 Jun 2005 09:06 GMT
> class Foo
> {
>     // the bug:
>     private static final DEFAULT_INSTANCE = new Foo();

Aha!

That's really quite a cute little bug ;-)

   -- chris
Timo Nentwig - 15 Jun 2005 19:23 GMT
> That's really quite a cute little bug ;-)

Isn't it? :) I must admit I'm somewhat proud of it indeed ;)                    


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.