Java类加载机制

    上文我们说到了JVM的内存模型,本文我们进一步的介绍JVM的类加载机制,先上一张很经典的图:

            

    由该图,我们开始展开探讨。上图将类加载的步骤分为七步,加载,验证,准备,解析,初始化,使用,卸载。

    一、加载

    获取和导入类的源文件。

    二、验证

    验证是连接的第一步,他的主要作用是用于检查二进制文件的合法性,只有当他符合JVM的要求才有效,否则可能会造成当前虚拟机的安全危害。

    三、准备

    是一个给类的静态变量在方法区分配内存并赋初始值阶段(非static修饰过的变量是在堆中分配空间,是在对象被实例化才开始分配),如:

public static int value=123;

    在准备阶段,它的值是0,只有到初始化阶段,他才会被赋值123。

    四、解析

    将常量池中的符号引用替换为直接引用的过程。(未理解)

    五、初始化

    为类加载连接的最后一步。当这个阶段,才开始执行Java代码,执行静态代码块,设置静态变量的值为程序员的预定值。

    一下情况下会初始化类:

  1.     new一个对象时(仅仅定义是不会初始化的);
  2.     读取类的静态变量以及静态方法时;
  3.     使用反射调用未被初始化的类时;(这个并无特别解释,只是在验证时发现,获取只有通过Class.forName()获取Class对象时,才会初始化,通过类名.class,并不会初始化,即使调用了Class对象中的方法)
  4.     初始化一个类时,会初始化他的父类;
  5.     JVM启动时,main方法的那个类;
    

    类初始化时,有父类的子类的初始化顺序:

    1、按照出现顺序,会依次初始化父类静态变量和静态代码块;

    2、再按照出现顺序,依次初始化子类的静态变量和静态代码块;

    3、初始化父类的普通变量以及构造方法;

    4、初始化子类的普通变量和构造方法;

    补充一个很经典的类加载例子:

public class SuperClass {
    static{
        System.out.println("SuperClass init!");
    }
    public static int value=123;

}
public class SubClass extends SuperClass {
    static{
        System.out.println("SubClass init!");
    }

}
public class NotInitialization {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(SubClass.value);

    }

}

    以上代码的执行结果为:

    SuperClass init!

    123

    由此得出结论,通过子类调用父类的静态变量,只会初始化父类,并不会初始化子类。对于静态字段来说,只有直接定义静态字段的那个类会被初始化。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值