When a class is loaded and initialized in JVM
Opened this issue · 0 comments
LiangShang commented
from http://javarevisited.blogspot.com/2012/07/when-class-loading-initialization-java-example.html
这篇主要介绍一下在JVM里,一个class什么时候被 加载(load),又是什么时候被 初始化(initialize)的。
When a class is loaded
一个class既可以在有一个class引用它的时候加载也可以在这个class需要被初始化的时候来加载。这个在JVM Specification 里没有明确规定,根据JVM的实现不同而不同。但是可以保证的是一旦有 static initialization,相应的类会被加载。
When a class is initialized
仅当以下情况出现时 class initialization 会执行。(from jvm8 specification)
翻译过来就是
- class的instance被创建
- class的非final的 static field被 get put invoke
- class 的静态方法被调用
- 反射
- 子类的初始化会调用父类初始化
- 声明了non-static non-abstract方法的 interface 会在实现这个interface的某个类被初始化时初始化
- JVM startup的初始类 (
public static void main(String[] args)
)
How class is initialized in Java
这一部分主要关注初始化的顺序
- 先声明的field(在上面的)先初始化。
- Super class 先于 sub class 初始化。
- 如果class initialization 是被 static field access 所触发的话,那么只有声明这个field的class才被初始化。如果在
Father
里声明而通过Child.field
调用的话只会初始化Father
。 - interface Initialization 不会触发 super interface initialization。
- static field 先于 non-static field 被初始化。
- 父类的 non-static field 先于 子类的 non-static field 被初始化。
下面有几个例子
/**
* Java program to demonstrate class loading and initialization in Java.
*/
public class ClassInitializationTest {
public static void main(String args[]) throws InterruptedException {
NotUsed o = null; //this class is not used, should not be initialized
Child t = new Child(); //initializing sub class, should trigger super class initialization
System.out.println((Object)o == (Object)t);
}
}
/**
* Super class to demonstrate that Super class is loaded and initialized before Subclass.
*/
class Parent {
static { System.out.println("static block of Super class is initialized"); }
{System.out.println("non static blocks in super class is initialized");}
}
/**
* Java class which is not used in this program, consequently not loaded by JVM
*/
class NotUsed {
static { System.out.println("NotUsed Class is initialized "); }
}
/**
* Sub class of Parent, demonstrate when exactly sub class loading and initialization occurs.
*/
class Child extends Parent {
static { System.out.println("static block of Sub class is initialized in Java "); }
{System.out.println("non static blocks in sub class is initialized");}
}
Output:
static block of Super class is initialized
static block of Sub class is initialized in Java
non static blocks in super class is initialized
non static blocks in sub class is initialized
false
/**
* Another Java program example to demonstrate class initialization and loading in Java.
*/
public class ClassInitializationTest {
public static void main(String args[]) throws InterruptedException {
//accessing static field of Parent through child, should only initialize Parent
System.out.println(Child.familyName);
}
}
class Parent {
//compile time constant, accessing this will not trigger class initialization
//protected static final String familyName = "Lawson";
protected static String familyName = "Lawson";
static { System.out.println("static block of Super class is initialized"); }
{System.out.println("non static blocks in super class is initialized");}
}
Output:
static block of Super class is initialized
Lawson