1

Is there a way to ensure that a class's static initialization is performed at runtime, and not on the first access of said class?

I am asking because I am currently using a library(of useful tools across multiple projects) but some of them take a reasonable amount of time to initialize. This leads to noticeable lag on the first access of said class, which is not good.

I do understand I can manually initialize it by adding a static method that I call myself at runtime, which does nothing, to force initialize that class, but if there is something I can do to ensure it will be initialized without manually calling an initialization method, that would be much better.

This is what I mean:

Utility Class:

public class Utility {
    public static final Map mapping = new HashMap();
    static {
        //Read file and fill in mappings
    }
}

Main Class:

public class Main {
    public void main(String[] args){
        //
        //Do things for a while
        //

        Object something = 
           Utility.mapping.get("else"); //Lag spike occurs here as the
                                        //static initialization was
                                        //only just now run
    }
}

This is what I currently do to force it, but requires me to call it manually:

Utility Class:

public class Utility {
    public static final Map mapping = new HashMap();
    static {
        //Read file and fill in mappings
    }

    public static void init(){}
}

Main Class:

public class Main {
    public void main(String[] args){
        Utility.init();     //Lag occurs here, where it belongs
        //
        //Do things for a while
        //

        Object something = 
           Utility.mapping.get("else"); //No lag spike now
    }
}
11
  • 3
    performed at runtime - how runtime is different from "first access"? Commented May 7, 2017 at 4:15
  • @Lashane The loading would occur first, and not in the middle of workflow when it can be noticed. Commented May 7, 2017 at 4:16
  • 1
    so, prolonged start of the application will not be noticed? Commented May 7, 2017 at 4:17
  • Yeah, you can just access the class once right at start up and it will look like part of the normal start up of the app. Though normally I think lazy initialization is better. I'm curious now: how exactly is the lag noticeable? Because there might be things you can actually do here rather than shift the lag to the start-up time. Commented May 7, 2017 at 4:20
  • Correct, or at the very least, would be better than having a lag spike at some undetermined moment later when it is first accessed. Commented May 7, 2017 at 4:21

2 Answers 2

1

There are a few ways:

  1. The simple way is to ensure that the real "first access" happens during initialization. It could be as simple as calling some dummy static method of the class to be initialized in your main(...) method.

  2. A slightly more sophisticated way to do it would be to have a list of class name strings that you want to force initialize, and use Class.forName(String) to load each one. (Note that this overload will force initialization.)

    The advantage of this approach is that your main doesn't need to depend on the APIs of the classes you are loading.

    Note that the name must be in the format returned by Class.getName(). For a reference type that is not an array type, this is fully-qualified name as you would typically write it in Java source code.

Sign up to request clarification or add additional context in comments.

3 Comments

That's an interesting idea, I'd forgotten that Class.forName() will also initialize a class file. Overall though I feel it might be better for the OP to just accept the lag, or maybe come up with a better (faster) way to initialize the class rather than apparently trying to load everything all at once.
@markspace - that is his decision. It depends on the nature of the application, including whether the initialization time is significant, and how much user impact the lags really have on the "user experience".
@StephenC This is great info, I didn't realize you could initialize that way.
0

Static blocks will get executed only when classes are loaded by the CLASS LOADERS and it requires the reference of the class. As you are referencing your Utility class for the first time in between the workflow, then it will be loaded at that moment and only then static variables got initialized.

If you have some kind of splash screens or any loading page which gets called for the first time when your application starts up then you can use below to initialize your class Class.forName("Utility"). Now your static variables are initialized on next use.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.