mysterious static

Discussion in 'Java' started by Timo Nentwig, Jun 13, 2005.

  1. Timo Nentwig

    Timo Nentwig Guest

    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, Jun 13, 2005
    #1
    1. Advertising

  2. Timo Nentwig

    Timo Nentwig Guest

    Timo Nentwig wrote:

    > This prints:


    If I call Foo.getDefaultCacheStrategy() from another class, of course :)
     
    Timo Nentwig, Jun 13, 2005
    #2
    1. Advertising

  3. Timo Nentwig

    Chris Uppal Guest

    Timo Nentwig wrote:

    > 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
     
    Chris Uppal, Jun 14, 2005
    #3
  4. Chris Uppal wrote:

    > Timo Nentwig wrote:
    >
    >
    >>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 ?


    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.

    --
    John Bollinger
     
    John C. Bollinger, Jun 14, 2005
    #4
  5. Timo Nentwig

    Timo Nentwig Guest

    Chris Uppal wrote:

    > Timo Nentwig wrote:
    >
    >> 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
    }
     
    Timo Nentwig, Jun 14, 2005
    #5
  6. Timo Nentwig

    Chris Uppal Guest

    Timo Nentwig wrote:

    > class Foo
    > {
    > // the bug:
    > private static final DEFAULT_INSTANCE = new Foo();


    Aha!

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

    -- chris
     
    Chris Uppal, Jun 15, 2005
    #6
  7. Timo Nentwig

    Timo Nentwig Guest

    Chris Uppal wrote:

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


    Isn't it? :) I must admit I'm somewhat proud of it indeed ;)
     
    Timo Nentwig, Jun 15, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bruce W.1

    Mysterious cookie problem

    Bruce W.1, Jul 29, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    367
    Michal A. Valasek
    Jul 29, 2003
  2. Ivan Demkovitch

    Mysterious problem with forms....

    Ivan Demkovitch, Oct 29, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    313
    Ivan Demkovitch
    Oct 29, 2003
  3. rh

    mysterious asp.net errors

    rh, Apr 23, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    464
  4. Max
    Replies:
    13
    Views:
    754
    Dimitri Glazkov
    Jan 4, 2005
  5. ryan groth

    (Mysterious) TypeLoadException Debugging

    ryan groth, Jun 23, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    1,452
    ryan groth
    Jun 23, 2005
Loading...

Share This Page