When is the static block of a class executed?

62,621

Solution 1

Yes, you are right. Static initialization blocks are run when the JVM (class loader - to be specific) loads StaticClass (which occurs the first time it is referenced in code).

You could force this method to be invoked by explicitly calling StaticClass.init() which is preferable to relying on the JVM.

You could also try using Class.forName(String) to force the JVM to load the class and invoke its static blocks.

Solution 2

Yes you are right, since you are not using your StaticClass it is not loaded by the vm and therefore init() is never executed.

For your second question, you probably have to go the hard way and scan all available classes and load them.

https://stackoverflow.com/a/3223019/393657

Solution 3

First of all class loading is different than class initialization. For anyone looking for explanation from Java Language Specification, when is static block executed - here it is.

The JLS §8.7 says that :

A static initializer declared in a class is executed when the class is initialized (§12.4.2).

So what does the initialization mean? Let's refer to JLS §12.4.2. This describes detailed initialization procedure. However point JLS §12.4.1 might be more appropriate here. It says that :

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
  • So to make the static initializer block to be executed automatically, you have to force one of those options to happen.

    Solution 4

    You are right, the easiest way is to access the class, for instance do a

    StaticClass.class.newInstance();

    Or something to that respect in your main method. This will ensure the class is loaded by the classloader.

    Solution 5

    Static block is executed when a loaded class is initialized or referenced first. Loading class doesnt mean that class is to initialized. JVM Class Loading is separate things to concern.

    Share:
    62,621

    Related videos on Youtube

    Leon
    Author by

    Leon

    Updated on July 05, 2022

    Comments

    • Leon
      Leon almost 2 years

      I have 2 jars, let's call them a.jar and b.jar.

      b.jar depends on a.jar.

      In a.jar, I defined a class, let's call it StaticClass. In the StaticClass, I defined a static block, calling a method named "init" :

      public class StaticClass {
        static {
          init();
        } 
      
        public void static init () {
          // do some initialization here
        }
      }
      

      in b.jar, I have a main, so in the main, I expect that the init() method has been called, but actually not. I suspect that is because the StaticClass has not been loaded by the jvm, could anyone tell me

      1. Is my conclusion correct?
      2. What triggers the jvm to load a class?
      3. How can I get the static block executed automatically?

      Thanks

      • Kris
        Kris about 12 years
        You would have to use your StaticClass somwhere so it will be loaded and initialized.
      • Andreas Baus
        Andreas Baus about 12 years
        It looks like this might answer your question.
      • Ciro Santilli OurBigBook.com
        Ciro Santilli OurBigBook.com about 9 years
    • Thomas
      Thomas about 12 years
      +1 for the hint on scanning all classes and automatically initializing those. It might be helpful to use a marker interface/annotation on the classes whose static initializer should automatically be executed (or any other defined static method). As said in the linked thread: Google Reflections might be a way to do that without much hassle.
    • Admin
      Admin over 7 years
      "which occurs the first time it is referenced in code" - not always. Accessing a static primitive type doesn't seem to be triggering the static blocks.
    • Marko Topolnik
      Marko Topolnik over 7 years
      "static initialization blocks are run when the JVM loads StaticClass` --- incorrect, class loading is distinct from class initialization.
    • Marko Topolnik
      Marko Topolnik over 7 years
      "which occurs the first time it is referenced in code" --- incorrect, implementation is free to decide when to load the class. Referencing the class is only the deadline when it definitely must be loaded.
    • Shafin Mahmud
      Shafin Mahmud over 7 years
      @MarkoTopolnik is right. "Static initialization blocks are run when the JVM loads StaticClass" is a wrong statement. static blocks executes during class initialization. " which is preferable to relying on the JVM" is another confusing statement, there is nothing to do with 'relying' in the case of StaticClass.init() , its simply a static method call.
    • user207421
      user207421 about 7 years
      'This is more preferable' why?
    • Pawel Dubiel
      Pawel Dubiel over 4 years
      I wonder if we can assume that: class is initialized when is referenced by name in a code that is already running.
    • Haozhun
      Haozhun over 3 years
      @hthserhs Public static final primitive types and string are inlined during javac. Therefore, there isn't really an "access" from the stand point of JVM. As a result, the behavior is understandable. I just want to add some context. What you said is certainly correct.
    • Alex R
      Alex R over 2 years
      The statement "which occurs the first time it is referenced in code" is completely wrong. The first time a class is referenced is often already at the import statement. Does importing a class trigger class loading? No. You can even write code like Class<MyClass> cls = MyClass.class; and Supplier<MyClass> s = () -> new MyClass() in your main method and as long as you don't call the suppliers get method, the class is not initialized and, therefore, the static block is not executed! (unless, ofc, the initialization happens by other means)