一.结论:
父类静态代码块,父类静态成员变量》》子类的静态代码块、子类的静态变量》》父类的普通代码块,父类普通成员变量,父类构造方法》》子类的普通代码块、子类普通成员变量、子类的构造方法
二、触发时间
1、静态代码块,静态成员变量:在类加载的时候被加载,比如在new时候会触发,通过类调用静态方法 或者静态变量,Class.forName
2、普通代码块、普通成员变量、构造方法:在每次实例化的时候被加载 比如new,invoke
三、代码
1.构建一个Father类
public class Father {
static{
System.out.println("father 静态代码块");
}
{
System.out.println("father 普通代码块");
}
public Father(){
System.out.println("父类 构造方法");
}
}
2.构建一个Son类
public class Son extends Father {
static{
System.out.println("Son 静态代码块");
}
public static GrandSon grandSon= new GrandSon();
{
System.out.println("Son普通代码块");
}
public Son(){
System.out.println("Son 构造方法");
}
public static void get(){
}
}
3.构建一个GrandSon类
public class GrandSon {
static{
System.out.println("GrandSon 静态代码块");
}
{
System.out.println("GrandSon 普通代码块");
}
public GrandSon(){
System.out.println("GrandSon 构造方法");
}
}
4.创建一个Test测试类
(1)new 创建实例
public class TestOrder {
public static void main(String[] args) throws ClassNotFoundException {
//类加载的两种常见方式:1,通过实例化(new、反射、class.forName) 2.通过调用静态的方法或者静态变量
new Son(); //会加载 父类的静态代码块》子类静态代码快》父类的非静态代码快、父类的构造方法》子类的非静态代码块、子类的构造方法
// Son.get();//知会加载父类的静态代码块》子类的静态代码块
// Class.forName("com.example.order.Son");
}
}
结果
(2)通过类调用静态方法
public class TestOrder {
public static void main(String[] args) throws ClassNotFoundException {
//类加载的两种常见方式:1,通过实例化(new、反射、class.forName) 2.通过调用静态的方法或者静态变量
// new Son(); //会加载 父类的静态代码块》子类静态代码快》父类的非静态代码快、父类的构造方法》子类的非静态代码块、子类的构造方法
Son.get();//知会加载父类的静态代码块》子类的静态代码块
// Class.forName("com.example.order.Son");
}
}
结果
(3)通过Class.forName
public class TestOrder {
public static void main(String[] args) throws ClassNotFoundException {
//类加载的两种常见方式:1,通过实例化(new、反射、class.forName) 2.通过调用静态的方法或者静态变量
// new Son(); //会加载 父类的静态代码块》子类静态代码快》父类的非静态代码快、父类的构造方法》子类的非静态代码块、子类的构造方法
// Son.get();//知会加载父类的静态代码块》子类的静态代码块
Class.forName("com.example.order.Son");
}
}
结果
四、理论分析
类的加载机制主要分为三步骤:
加载、连接、初始化
在加载中会将class中的静态结构转化为JVM中运行时数据区的对象,并完成检验与初始化
具体理论后续待看完周志明的《深入理解java虚拟机》