Java进阶架构师之路JavaJava 杂谈

JVM核心教程之JVM运行与类加载全过程详解

2019-06-15  本文已影响5人  88b61f4ab233

为什么研究类加载全过程?

类加载机制

例1:

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; //静态变量,静态域 field
    static{
        System.out.println("静态初始化类A");
        width = 300 ;
    }
    public A() {
        System.out.println("创建A类的对象");
    }
}

分析:

说明:

内存中存在栈、堆(放创建好的对象)、方法区(实际也是一种特殊堆)

1、JVM加载Demo01时候,首先在方法区中形成Demo01类对应静态数据(类变量、类方法、代码…),同时在堆里面也会形成java.lang.Class对象(反射对象),代表Demo01类,通过对象可以访问到类二进制结构。然后加载变量A类信息,同时也会在堆里面形成a对象,代表A类。

2、main方法执行时会在栈里面形成main方法栈帧,一个方法对应一个栈帧。如果main方法调用了别的方法,会在栈里面挨个往里压,main方法里面有个局部变量A类型的a,一开始a值为null,通过new调用类A的构造器,栈里面生成A()方法同时堆里面生成A对象,然后把A对象地址付给栈中的a,此时a拥有A对象地址。

3、当调用A.width时,调用方法区数据。

当类被引用的加载,类只会加载一次

例2:

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

    public static void main(String[] args) throws Exception {
        System.out.println("Demo01的main方法!");
        System.out.println(System.getProperty("java.class.path"));

        //主动引用
//        new A();
//        System.out.println(A.width);
//        Class.forName("com.sinosoft.test.A");

        //被动引用
//        System.out.println(A.MAX);
//        A[] as = new A[10];
        System.out.println(B.width);//B类不会被加载

    }
}

class B  extends A {
    static {
        System.out.println("静态初始化B");
    }
}

class A extends A_Father {
    public static int width=100;   //静态变量,静态域    field
    public static final  int MAX=100; 

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

class A_Father extends Object {
    static {
        System.out.println("静态初始化A_Father");
    }
}
上一篇 下一篇

猜你喜欢

热点阅读