views:

547

answers:

4

Once a class is loaded is there a way to invoke static initializers again?

public class Foo {

    static {
     System.out.println("bar");
    }

}

Edit:

I need to invoke the static initializer because I didn't write the original class and the logic I need to invoke is implemented in the static initializer.

+9  A: 

Put the initalisation code in a separate public static method, so you can call it from the static initializer and from elsewhere?

Daniel Earwicker
I can't modify the code. It's in a third party library and I don't intend to create my own distribution of it with the code in a regular static method. :) The solution I've used was to copy and paste the code in another class so it can be in a regular static method. But I didn't like it. DRY
Kalecser
Hm... then my next question is, why does that 3rd party class have logic in a static initializer that you might want to reinvoke?!
Daniel Earwicker
It will load and process an XML config file on the static initializer, i want to reload the xml.
Kalecser
The static initilizer has 70 + LOC.
Kalecser
Ugh... you have my sympathy! :)
Daniel Earwicker
+3  A: 

I agree with Earwicker's answer. Just extract the static initialization to a separate static method.

public class Foo {

    static {
        Foo.initialize();
    }

    public static void initialize() {
        System.out.println("bar");
    }

}
bruno conde
Why the downvote? Can the person who downvoted me can to explain why?
bruno conde
+3  A: 

One circumstance in which the logic would be run more than once is if the class is loaded multiple times by different ClassLoaders. Note that in this instance, they are essentially different classes.

Generally, though, these are one-shot deals. If you want to be able to invoke the logic multiple times, do as others have suggested and put it in a static method.

McDowell
I was trying to find a reference about classloaders but couldn't find a good one. Do you have one?
Michael Myers
Alas, no. My knowledge is cobbled together from the VM spec, the javadoc, server manuals and various internet sources. You could do worse than Googling "developerWorks" and "ClassLoader".
McDowell
A: 

you could try extending the class which contains the static code, and then put in your own static initializer. Not quite sure if it works, but :

public class OldBadLibraryClass {
   static {
      System.out.println("oldBadLibrary static init");
   }
}

//next file

public class MyBetterClass extends OldBadLibraryClass {
   static {
      System.out.println("MyBetterClass init");
   }
}


public class Test {
   public static void main(String[] args) {
      new MyBetterClass();
   }
}

see if the above prints in the order you expect. On my machine, it worked.

Though this is totally a hack, and is quite brittle. It would really be much better to modify the old class to have an init() method that can be overridden.

Chii