Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does .class not invoke the static block in a Class?

This is the code I have:

public class StupidClass {     static {         System.out.println("Stupid class loaded!");     } } 

And the tests I have, which I run separately.

import org.junit.Test;  public class StupidTest {     @Test     public void foo() throws ClassNotFoundException {         final Class<?> stupidClass = Class.forName("StupidClass");         System.out.println(stupidClass.getSimpleName());     }      @Test     public void bar() throws ClassNotFoundException {         final Class<StupidClass> stupidClassClass = StupidClass.class;         System.out.println(stupidClassClass.getSimpleName());     } } 

When I run test foo I will see:

Stupid class loaded! StupidClass 

But when I run the test bar all I see is:

StupidClass 

Quoting from this page..

Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.

So my understanding is, in test bar, Stupid class is loaded, otherwise I would have seen a null I guess? So Class object is created because class itself is loaded..

And now quoting from this page

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).

So I am expecting to see the "Stupid class loaded!" text in test bar as well, but I am not.

Also quoting from Thinking in Java

Each of the classes Candy, Gum, and Cookie has a static clause that is executed as the class is loaded for the first time.

which is not very accurate it seems..

What am I missing?

like image 975
Koray Tugay Avatar asked Sep 15 '16 07:09

Koray Tugay


People also ask

Can we have static block in a class?

A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

How do you call a static block in class?

You can use Class. forName("com. the. ClassName"); to call static block without ceating any instance of that class.

Why static blocks are not allowed in interface?

Mainly, static blocks are used to initialize the class/static variables if you have not initialized them at the time of declaration. In case of interfaces when you declare a field in it. It is mandatory to assign value to it else, a compile time error is generated.

Will static block be executed with final variable?

We can initialize a final static variable at the time of declaration. Initialize inside a static block : We can also initialize a final static variable inside a static block because we should initialize a final static variable before class and we know that static block is executed before main() method.


1 Answers

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).

The above quote is plain wrong, but it is just one instance of a very widespread misconception.

  1. Class is not initialized when it's being loaded, but when a static class member is first referenced. This is precisely governed by the specification.

  2. Class loading does not occur when the class is first referenced, but at an implementation-dependent point.

  3. The last moment when the class must be loaded is when the class is referenced, which is not the same as referencing a class member.

Class.forName initializes the class by default, but you have the choice of calling an overload that takes a boolean initialize and supplying false. You'll get the class loaded without initializing.

like image 178
Marko Topolnik Avatar answered Sep 28 '22 02:09

Marko Topolnik