Why doesn't the class call a static block in the class?

This is the code I have:

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

And the tests that I have that 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 the foo test, I will see:

 Stupid class loaded! StupidClass 

But when I run the bar test, I see the following:

 StupidClass 

Quote from this page .

Class objects are automatically created by the Java Virtual Virtual Machine. The machine boots as classes and calls to the defineClass method in the class loader.

So, I understand that the Stupid class is loaded in the test panel, otherwise I would see zero, I think? Thus, the class object is created because the class itself is loading.

And now, linking to this page

Static initialization blocks are triggered when the JVM (class loader - be specific) loads StaticClass (which is the first time a link to the code occurs).

So, I expect to see the "Stupid class loaded!" text in the test panel, but I do not know.

Also cited Thinking in Java

Each of the Candy, Gum, and Cookie classes has a static clause that runs when the class first loads.

which is not very accurate, it seems.

What am I missing?

+68
java initialization static class
Sep 15 '16 at 7:00
source share
2 answers

Static initialization blocks are triggered when the JVM (the class loader is specific) loads the StaticClass (which happens the first time it is accessed in the code).

The above quote is incorrect, but this is just one example of a very common misconception.

  • The class is not initialized when it is loaded, but when the static member of the class is first referenced. This is precisely determined by the specification .

  • Class loading does not occur when the class is first referenced, but at a point that is implementation dependent.

  • The last moment when the class should be loaded is when the class refers, which does not match the reference to the class member.

Class.forName initializes the default class, but you have the choice of invoking the overload, which accepts boolean initialize and provides false . You will get a class loaded without initialization.

+59
Sep 15 '16 at 7:17
source share
β€” -

Loading and initializing classes are two different things. A class can be loaded, but not initialized, until it is really needed. Static initializers are launched only when the class <> NOT is loaded, "initialized"

In the first case, you load and initialize the class when using class.forName() , so the static initializers are started and, therefore, you see "Stupid class loaded!" as a conclusion. In the second case, you simply assign a class reference, the class is loaded (use java -verbose: class to see which classes are loaded), but you don’t actually initialize it (or rather, do nothing that causes the initializers to start). So you do not see the output as a Stupid class loaded! . Try doing something like calling newInstance() on a class, it should force the class to initialize, and you should see a Stupid class loaded!

My code is:

 public class CheckPalindrome { public static void main(String[] args) { Class<Test> t = Test.class; } } // class being loaded class Test { static { System.out.println("aaa"); } } 

Loaded Classes

 ... [Loaded Test from file:/Workspaces/SampleTest/Java8/bin/] ... 

^ - This indicates that the class is loaded but not initialized.

+22
Sep 15 '16 at 7:14
source share



All Articles