JAVA-类隔离机制

本文详细介绍了Java中的类加载过程,包括BootstrapClassLoader、ExtensionClassLoader和AppClassLoader等类加载器的角色,以及类加载的7个阶段。类加载采用双亲委托模型,确保类的安全性和唯一性。同时,文章阐述了类加载的时机,如创建对象、访问静态字段等,并说明了有继承关系和无继承关系的类成员加载顺序。
摘要由CSDN通过智能技术生成

一、类加载:

        1、类加载:Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码加载到内存,发给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行,最终形成可以被jvm直接使用的Java类型;

 

1、Bootstrap ClassLoader:负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
2、Extension ClassLoader:负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
3、App ClassLoader:负责记载classpath中指定的jar包及目录中class
4、Custom ClassLoader:属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader

 

        2、类加载的好处:在java启动的时候运行中完成类、链接、初始化的动作,提高java程序的灵活性。

        3、类加载7个阶段:加载  ->  验证  ->  准备  ->  解析  ->  初始化  ->  使用  ->  卸载

        4、类加载时机

->  以下5中情况,虚拟机规范则是严格规定了必须立即对类进行初始化
1、new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用类的静态方法的时候。
2、使用java.lang.reflect包的方法对类进行反射调用的时候。
3、初始化一个类的子类的时候。若其父类未被初始化,则先触发父类的初始化。
4、虚拟机执行启动时,被标明为启动类的类(包含main的类)。
5、使用jdk1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后解析结果是REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

二、类的加载流程:双亲委托

        1、一个AppClassLoader查找资源时,先看看缓存是否有,缓存有从缓存中获取,否则委托给父加载器。 
        2、递归,重复第1部的操作。 
        3、如果ExtClassLoader也没有加载过,则由Bootstrap ClassLoader出面,它首先查找缓存,如果没有找到的话,就去找自己的规定的路径下,也就是sun.mic.boot.class下面的路径。找到就返回,没有找到,让子加载器自己去找。 
        4、Bootstrap ClassLoader如果没有查找成功,则ExtClassLoader自己在java.ext.dirs路径中去查找,查找成功就返回,查找不成功,再向下让子加载器找。 
        5、ExtClassLoader查找不成功,AppClassLoader就自己查找,在java.class.path路径下查找。找到就返回。找不到则抛异常。

 三、类的加载顺序:

         I、有继承关系的加载顺序:父静态->子静态->父变量->父构造方法->子变量->子构造方法

1.首先加载父类的静态字段或者静态语句块
2.子类的静态字段或静态语句块
3.父类普通变量以及语句块
4.父类构造方法被加载
5.子类变量或者语句块被加载
6.子类构造方法被加载

        II、没有继承关系的加载顺序

        

public class Test3 {
    public static void main(String[] args) {
        new Test3();                         //4.第四步,new一个类,但在new之前要处理匿名代码块
    }

    static int num = 4;                    //2.第二步,静态变量和静态代码块的加载顺序由编写先后决定

    {
        num += 3;
        System.out.println("b");           //5.第五步,按照顺序加载匿名代码块,代码块中有打印
    }

    int a = 5;                             //6.第六步,按照顺序加载变量

    { // 成员变量第三个
        System.out.println("c");           //7.第七步,按照顺序打印c
    }

    Test3() { // 类的构造函数,第四个加载
        System.out.println("d");           //8.第八步,最后加载构造函数,完成对象的建立
    }

    static {                              // 3.第三步,静态块,然后执行静态代码块,因为有输出,故打印a
        System.out.println("a");
    }

    static void run()                    // 静态方法,调用的时候才加载// 注意看,e没有加载
    {
        System.out.println("e");
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值