类加载机制(一)

2018-09-07  本文已影响0人  guozhk

加载机制系列
类加载机制(一)
类加载机制(二)
类加载机制(三)

类加载机制

1.JVM把class文件加载到内存,对数据进行校验,解析,初始化 最终形成JVM可以直接使用的过程

image.png
加载

将class文件字节码加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个该类的java.lang.Class对象,作为方法区类数据的访问入口
该过程需要类加载器的参与。


image.png
链接
初始化

demo

public class Demo01 {
    
    public static void  main(String[] args) {
        A a= new A();
        System.out.println(A.width);
        
    }

}

class A{
    
    public static int width =100;
    
    static {
        
        System.out.println("静态初始化类");
        width = 300;
    }
    
    public A() {
        System.out.println("创建A对象");
    }
    
}

运行结果:

静态初始化类
创建A对象
300

内存加载分析


image.png

1.先把demo01的代码字节码加载到方法区
2.同时在堆中生成java.lang.class对象(反射对象)
3.把A的代码字节码加载到方法区
4.同时在堆中生成java.lang.class对象(反射对象)
5.栈中main方法栈 中A a=null
调用new A()
6.A()方法栈
7.实例化A对象在堆中生成对象A 把main方法栈中 a的地址引用指向堆中A对象

类的加载全过程

类的主动引用(会初始化)
类的被动引用(不会初始化)

Demo


public class Demo01 {

    static {
        System.out.println("静态初始化类Demo01");
    }

    public static void main(String[] args) {
        System.out.println("Demo01的main() 方法");
        A a = new A();
        System.out.println(A.width);

    }

}

class A_Father {

    public static int father_width=10;
    
    public final static int father_final_test=333;
    
    
    
    
    static {
        System.out.println("静态初始化类A_father");

    }
}

class A extends A_Father {

    public static int width = 100;

    static {

        System.out.println("静态初始化类A");
        width = 300;
    }

    public A() {
        System.out.println("创建A对象");
    }

}

结果:
先初始化A的父类 A_Father

静态初始化类Demo01
Demo01的main() 方法
静态初始化类A_father
静态初始化类A
创建A对象
300

修改main方法

public static void main(String[] args) {
//      System.out.println("Demo01的main() 方法");
//      A a = new A();
        //调用A的静态域
        System.out.println(A.width);

    }

结果:A类被加载初始化

静态初始化类Demo01
静态初始化类A_father
静态初始化类A
300

再次修改直接用反射调用

public static void main(String[] args) throws Exception{
//      System.out.println("Demo01的main() 方法");
//      A a = new A();
        
        //调用A的静态域
        //System.out.println(A.width);
        
        //反射调用
        Class.forName("com.org.test.init.A");
    }

结果:A类被加载初始化

静态初始化类Demo01
静态初始化类A_father
静态初始化类A

调用常量:

public static void main(String[] args) throws Exception{
//      System.out.println("Demo01的main() 方法");
//      A a = new A();
        
        //调用A的静态域
        //System.out.println(A.width);
        
        //反射调用
        //Class.forName("com.org.test.init.A");
        //调用常量
        System.out.println(A_Father.father_final_test);
        
    }

结果:类没有加载初始化

静态初始化类Demo01
333

调用父类静态域


    public static void main(String[] args) throws Exception{
//      System.out.println("Demo01的main() 方法");
//      A a = new A();
        
        //调用A的静态域
        //System.out.println(A.width);
        
        //反射调用
        //Class.forName("com.org.test.init.A");
        //调用常量
        //System.out.println(A_Father.father_final_test);
        
        //调用父类静态变量
        System.out.println(A_Father.father_width);
                
        
    }

结果:只有父类被加载初始化

静态初始化类Demo01
静态初始化类A_father
10

数组引用:

public static void main(String[] args) throws Exception{
//      System.out.println("Demo01的main() 方法");
//      A a = new A();
        
        //调用A的静态域
        //System.out.println(A.width);
        
        //反射调用
        //Class.forName("com.org.test.init.A");
        //调用常量
        //System.out.println(A_Father.father_final_test);
        
        //调用父类静态变量
        //System.out.println(A_Father.father_width);
        
        //数组变量引用
        A[] as= new A[10];
                
        
    }

结果:类不会被加载

静态初始化类Demo01
上一篇 下一篇

猜你喜欢

热点阅读