Kor*_*gay 68 java static initialization class
这是我的代码:
public class StupidClass {
static {
System.out.println("Stupid class loaded!");
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试,我分开运行.
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());
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行test foo时,我会看到:
Stupid class loaded!
StupidClass
Run Code Online (Sandbox Code Playgroud)
但是,当我运行测试栏时,我看到的是:
StupidClass
Run Code Online (Sandbox Code Playgroud)
从这个页面引用..
类对象由Java虚拟机在加载类时自动构造,并通过调用类加载器中的defineClass方法来构造.
所以我的理解是,在测试栏中,Stupid类被加载,否则我会看到一个null我猜?因此创建了Class对象,因为类本身已被加载.
现在引用这个页面
当JVM(类加载器 - 要特定)加载StaticClass(第一次在代码中引用时出现)时,运行静态初始化块.
所以我期待看到"愚蠢的课程加载!" 测试栏中的文字也是,但我不是.
同样引用Thinking in Java
Candy,Gum和Cookie中的每个类都有一个静态子句,该子句在第一次加载类时执行.
这似乎不是很准确..
我错过了什么?
The*_*ind 22
类加载和初始化是两个不同的事情.可以加载一个类,但在真正需要之前不进行初始化.静态初始化程序仅在初始化类时运行<> NOT loaded,"initialized"
在第一种情况下,您在使用时加载并初始化类class.forName(),这就是静态初始化程序运行的原因,因此您将其"Stupid class loaded!"视为输出.在第二种情况下,你只是分配一个类的引用,该类被加载(使用java -verbose:class来查看加载了哪些类),但你并没有真正初始化它(或者更确切地说,没有做任何迫使初始化程序运行的东西).因此,您不会将输出视为Stupid class loaded!.尝试做类似调用newInstance()类,它应该强制类的初始化,你应该看到Stupid class loaded!
我的代码:
public class CheckPalindrome {
public static void main(String[] args) {
Class<Test> t = Test.class;
}
}
// class being loaded
class Test {
static {
System.out.println("aaa");
}
}
Run Code Online (Sandbox Code Playgroud)
加载的类
...
[Loaded Test from file:/Workspaces/SampleTest/Java8/bin/]
...
Run Code Online (Sandbox Code Playgroud)
^ - 这表明该类已加载但未初始化.