Java: use static initializer blocks to register cl

2020-04-16 07:15发布

问题:

I have an Eclipse Plug-in with references to some JARs files (which where configured in the Runtime tab of the MANIFEST.MF). I can access and instantiate classes contained in those JARs files, so they are contained in the classpath.

I wanted the classes to register themselves to a global static registry, so I added a static initializer block to all of them:

public class SomeStrategy extends Strategy {

    static {
        StrategyRegistry.register("SomeStrategy", SomeStrategy.class);
    }

}

I have several of those classes which should all register themselves to the StrategyRegistry (which is just a static class with a hashmap). However, whenever I access the StrategyRegistry, it doesn't hold any values.

I read that the static initializers are executed when the class is first loaded and since I do not reference those classes anywhere in code directly, they are not loaded and the static initializers are not executed.

My question is now: can I change the code so that my classes self-register themselves with static initializers? I explicitely don't want to create a settings file holding the registration and reading that on program startup. A in-class solution (which I don't know if even possible) would be preferred.

回答1:

I read that the static initializers are executed when the class is first loaded and since I do not reference those classes anywhere in code directly, they are not loaded and the static initializers are not executed.

This is correct -- unless you access the class somewhere, none of its code is ever executed. Creating an instance of the class or accessing a static property on the class will result in its static initializer being called, but otherwise, no code will be run.

This rule enforces ordering on the calling of static initializers, that is, it ensures that the static initializer is always called before anything tries to access any properties of the class, and also avoids a problem of having every static initializer for every class fire immediately on program startup.

I am not aware of any way to cause code on a class or object to run without having something somewhere access that class or object.



回答2:

First of all you should know that your static code block will never be called until you access Class file. I mean you should access at least one time to your class file something like SomeStrategy.doSomething() or SomeStrategy s = new SomeStrateg() These codes will access your class file and before doing anything your static block will be called then methods which you try to call will be called. Finally if you want to register each class you can create a Registrar class and it will create each instance of your classes that will be registrered.It will cause to call your static code block.