Java类加载机制
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java类加载机制,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3948字,纯文字阅读大概需要6分钟。
内容图文
![Java类加载机制](/upload/InfoBanner/zyjiaocheng/814/3f9365bd31eb40c39d7cedc8354c6c54.jpg)
类加载器的种类
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042456943.jpg)
- 启动类加载器(Bootstrap ClassLoader)
System.out.println(System.getProperty("sun.boot.class.path"));
执行结果:D:javajdkjrelib esources.jar;D:javajdkjrelib t.jar;D:javajdkjrelib sunrsasign.jar;D:javajdkjrelibjsse.jar;D:javajdkjrelibjce.jar;D:javajdkjrelibcharsets.jar;D:javajdkjrelibjfr.jar;D:javajdkjreclasses
负责加载JRE的核心类库,如JRE目标下的rt.jar,charsets.jar等。
- 扩展类加载器(Extension ClassLoader)
System.out.println(System.getProperty("java.ext.dirs"));
执行结果:D:javajdkjrelibext;C:WindowsSunJavalibext
负责加载JRE扩展目录ext中jar类包
- 系统类加载器(Application ClassLoader)
System.out.println(System.getProperty("java.class.path"));
执行结果:D:javajdkjrelibcharsets.jar;D:java epostorycomalibabaastjson.2.49astjson-1.2.49.jar;D:java epostorymysqlmysql-connector-java.1.14mysql-connector-java-5.1.14.jar;D:SoftIntelliJ IDEAIntelliJ IDEA 2018.2.6libidea_rt.jar。由于执行结果太长我这里就贴了一部分。
负责加载ClassPath路径下的类包
- 用户自定义加载器(User ClassLoader)
负责加载用户自定义路径下的类包
类加载器面试问题
System.out.println(String.class.getClassLoader());
这是一道比较常见的题,本意是查看String用的什么类加载器,String属于rt.jar java.lang.string,但是执行结果为null。
rt.jar 是由Bootstrap ClassLoader来加载,但是Bootstrap ClassLoader不继承自ClassLoader,因为它不是一个普通的Java类,底层由C++编写,已嵌入到了JVM内核当中,当JVM启动后,Bootstrap ClassLoader也随着启动,负责加载完核心类库后。总结一句话来说就是他是由C++编写的,所以查看String类加载器得到的结果为null。
类加载机制
全盘负责委托机制
当一个ClassLoader加载一个类的时候,除非显示的使用另一个ClassLoader,该类所依赖和引用的类也由ClassLoader载入。
双亲委派机制
指先委托父类加载器寻找目标类,在找不到的情况下载自己的路径中查找并载入目标类。
双亲委派模式的优势
沙箱安全机制:比如自己写的String.class类不会被加载,这样可以防止核心库被随意篡改。
避免类的重复加载:当父ClassLoader已经加载了该类的时候,就不需要子CJlassLoader再加载一次。
几种方式加载class文件?
jar、网络传输二进制文件、本地系统加载二进制文件、数据库存放class文件、jit动态加载。
加载机制面试问题
用网络传输的方式和jar包加载的方式加载同一个class文件,那么在jvm中这两个类是否相同?
答案:虽然是同一份class字节码文件,但是由于被两个不同的ClassLoader实例所加载,所以JVM认为它们就是两个不同的类。
类的生命周期
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042457005.jpg)
加载阶段:磁盘中的class文件加载到内存中(方法区)。
连接阶段:
验证:1、class文件格式验证 魔术因子、主次版本号;
2、元数据验证 是否有父类、final不能进行重写;
3、字节码验证 指令、选择、循环;
4、符号验证 Person person = new Person();
准备:根据类型进行初始化赋值 int 0。
解析:符号引用 -> 直接引用 类装载器装入类所引用的其他类
四类解析:
类接口:是否数组类型(被动加载)-> 给一组空间, 否则直接初始化并给初始化空间
字段解析:本类字段 父类空间
类方法解析:当前类中找 -> 父类 -> NoSuchMethodError
接口方法的解析:实现类中的方法
准备过程中有一道经典的面试题:在准备阶段以下两个参数的值分别的多少?
public final static int age = 10;
public static int age = 10;
答案:用final修饰的属于常量在准备过程中就已经赋值所以等于10;没有用final修饰的则值为0。
生命周期中比较重要的概念
符号引用:javac 编译过程中不分配存储空间,new Person();用助记符来表示,实际上并不是真正的存储空间。
直接引用:在第二链接阶段的解析过程中由符号引用转换为直接引用,这个时候才真正分配存储空间。
主动使用:不使用的时候也加载。
被动使用:在使用的时候再加载,也就是所谓的延迟加载。
Java中的6种主动使用
这里我们简单准备了两个测试用的类,下面我们进行简单的测试
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042457283.jpg)
Person类
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042457399.jpg)
场景一:
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042457542.jpg)
new 的过程中引起了类的主动加载
场景二:
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042457651.jpg)
访问类的静态变量
场景三:
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042457930.jpg)
访问类的静态方法
场景四:
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042458165.jpg)
反射调用
场景五:
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042458318.jpg)
初始化子类引起父类的主动使用
场景六:其实细心的小伙伴可能已经发现了,main方法作为一个入口肯定会引起主动加载的。
例举两种被动使用的情况
场景一:
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042458451.jpg)
对象数组初始化
场景二:
这里先把Person中的age变量前面加上final
public final static int age = 10;
![Java类加载机制 - 文章图片](/upload/getfiles/0001/2021/5/5/20210505042458507.jpg)
调用静态常量
总结
Jvm这部分东西实际工作中用到的其实微乎其微,更多的是用来应对面试,当然也并不是说了解这些东西没有必要,如果能真正理解的话对你实际工作也还是有一定的帮助的,就比如上面提到的面试题你先看看自己是否都能答上来。
内容总结
以上是互联网集市为您收集整理的Java类加载机制全部内容,希望文章能够帮你解决Java类加载机制所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。