A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© z_one 中级黑马   /  2015-11-9 17:44  /  268 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

先列出虚拟机在类加载过程中的一些概念和规范:
1、类在虚拟机中的整个生命周期可以分为七个阶段:
        加载=》验证=》准备=》解析=》初始化=》使用=》卸载
其中类的加载过程(跟字节码加载不是一回事)必须按照如下顺序开始:
        加载=》验证=》准备=》初始化
2、上面的初始化跟对象实例化不是一个概念,但又有关联,虚拟机中有且只有5中情况必须立即对类进行“初始化”,加载、验证、准备自然在此前之开始
        (1、遇到new、gestatic、pustatic、invokestatic这4条字节码指令时,如果类没有进行初始化,则需要先触发其初始化。而这4条指令常见的java代码场景是:使用new实例化对象,问题中创建对象正是这样;读取或设置一个类的静态字段(下面主类2中如此,但是主类1、3被final修饰的情况除外);调用一个类的静态方法。
        (2、使用reflect方法对类进行反射的时候
        (3、当初始化一个类的时候,若发现父类还没进行初始化,则需先触发其父类进行初始化,问题中正是此场景
        (4、启动虚拟机时,主类(含有main方法)会先被初始化
        (5、JDK1.7动态语言支持时,若MethodHandle实例最后的解析结构RRE_getStatic、REF_invokeStatic、REF_putStatic的方法句柄,若这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。
3、在加载阶段,虚拟机需要完成以下3件事情:
        (1、通过一个类的全限定名来获取定义此类的二进制字节流(可以从文件或者网络获取)。题主要问的应该就是先加载那个类的字节流
        (2、将这个字节流所所代表的静态存储结构转化为方法区的运行时数据结构
        (3、在内存中生成一个代表这个类的Class对象,最为方法区中对这个类的各种数据访问入口

从上面这些规范中只能得出父类先于子类进行初始化,但是不能得出父类一定在子类之前加载,这没有明确规定,只能看具体的实现。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马