1. JVM会先去方法区中找有没有相应类的.class存在。如果有,就直接使用;如果没有,则把相关类的.class加载到方法区
2. 在.class加载到方法区时,会分为两部分加载:先加载非静态内容,再加载静态内容
3. 加载非静态内容:
把.class中的所有非静态内容加载到方法区下的非静态区域内
4. 加载静态内容:
把.class中的所有静态内容加载到方法区下的静态区域内
静态内容加载完成之后,对所有的静态变量进行默认初始化
所有的静态变量默认初始化完成之后,再进行显式初始化
当静态区域下的所有静态变量显式初始化完后,执行静态代码块
5. 当静态区域下的静态代码块执行完之后就完成整个类的加载
public class Demo01 {
public static void main(String[] args) {
B b = new B();
}
}
class A {
static String str1 = "父类A的静态变量";
String str2 = "父类A的非静态变量";
static {
System.out.println("执行了父类A的静态代码块");
}
{
System.out.println("执行了父类A的非静态代码块");
}
public A() {
System.out.println("执行了父类A的构造方法");
}
}
class B extends A {
static String str1 = "子类B的静态变量";
String str2 = "子类B的非静态变量";
static {
System.out.println("执行了子类B的静态代码块");
}
{
System.out.println("执行了子类B的非静态代码块");
}
public B() {
System.out.println("执行了子类B的构造方法");
}
}
- 执行了父类A的静态代码块
- 执行了子类B的静态代码块
- 执行了父类A的非静态代码块
- 执行了父类A的构造方法
- 执行了子类B的非静态代码块
- 执行了子类B的构造方法
加载顺序
父类的静态变量
父类的静态代码块
【子类】的静态变量
【子类】的静态代码块
父类的非静态变量
父类的非静态代码块
父类的构造方法
【子类】的非静态变量
【子类】的非静态代码块
【子类】的构造方法
public class LazyLoading {
public static void main(String[] args) throws Exception {
//P p; //没有new对象不会被加载
//Q q = new Q(); //new对象之后【需要】被加载 ==》staticP staticQ noneP initP noneQ initQ
//System.out.println(P.i); //打印final值【不需要】加载整个类 ==》8
//System.out.println(P.j); //打印非final值【需要】加载整个类 ==》staticP 9
//System.out.println(P.method1()); //打印static方法【需要】加载整个类 ==》staticP method1
//System.out.println(P.method2()); //打印static方法【需要】加载整个类 ==》staticP method2
//Class.forName("com.LazyLoading$P"); //【需要】被加载 ==》staticP
}
public static class P {
static final int i = 8;
static int j = 9;
private P() {
System.out.print("initP" + "\t");
}
{
System.out.print("noneP" + "\t");
}
static {
//只要被加载过这个static一定是被打印出来的,因为一个类加载内存之后他有这几个步骤:
//1.Loading 2.Linking 3.Initialization 这个过程会执行静态语句块。
System.out.print("staticP" + "\t");
}
static String method1() {
return "method1";
}
static final String method2() {
return "method2";
}
}
public static class Q extends P {
public Q() {
System.out.print("initQ" + "\t");
}
{
System.out.print("noneQ" + "\t");
}
static {
System.out.print("staticQ" + "\t");
}
}
}