JAVA类加载机制,类加载过程,ClassLoader类加载器,类加载器关系
JAVA类加载机制
- JAVA类加载器
- 类加载层次关系
- 类加载机制的特性
JAVA类加载机制
JAVA类加载器
java类加载器负责把一个一个编译好的class文件装入内存中,并为其创建对应的java.lang.Class对象。加载器是java动态特性的核心,提供了多态特性以及服务器热部署的能力。
java中有如下几种类加载器:
BootstrapClassLoader
- implemented by native language (C/C++/汇编。区别于JRE版本。其他loader都是java)
- load the core classes of JDK
ExtesionClassLoader
- loader the class from jre/lib/ext
ApplicationClassLoader
- load user-define classes
- ClassLoader.getSystemClassLoader() == application class loader
other class loaders
- SecureClassLoader
- URLClassLoader (2/3的父类)
- user-define ClassLoader
类加载层次关系:
!!非继承关系.
(图片摘自马士兵老师教程)
每次ClassLoader加载类时,都会向上层询问是否已经加载该类,若已加载,则不会再加载。一方面节省资源,另一方面出于安全的考虑,保护核心class不会被覆盖。
按需加载,用到的时候再加载(new / class.forName() / classLoader.load())
URLClassLoader是ApplicationClassLoader、ExtesionClassLoader的父类,主要负责显式的指明类加载的path。
类加载机制的特性:
- 全盘负责
- 父类委托
- 缓存机制
全盘负责是指,当一个类加载器负责加载某个Class时,还要负责加载该Class的引用和依赖(除非有显式声明指定让其他加载器来加载)。
父类委托是指,类加载器再载入类的时候,会优先让parent加载器(关系中的)来加载,当该parent加载器无法载入指定类时,才会尝试从自己的类路径加载该类。[递归定义*]
缓存机制是指,jvm会保证所有加载过的Class都会被缓存下来,当程序要使用某个Class时,会优先在缓存里搜索该类(如何辨别?),若搜索不到则载入该类class文件,并将其转换成Class对象。[这也导致了,我们修改程序后,必须重启应用程序(JVM)才能生效]
JVM如何辨别是不是同一个类:
符合类标识规则(类名,包名,加载器名)的类才会被认为是同一个类。
类加载流程:
其中:
第5.6步允许用户重写ClassLoader中的findClass()方法来实现自己的载入策略,甚至可以重写loadClass()方法来具体实现整个载入过程。
tips:
- java -verbose:class 可以观察类的具体加载过程
- static 语句块在加载后只执行一次
- dynamic语句块每次new新的对象都会执行{ }
等同于无条件 ‘在所有构造语句之前的执行的’ 语句。
源码:
https://github.com/timo1160139211/java-tranning/tree/master/src/site/gaoyisheng/test/classloader
在线画图工具:
https://go.gliffy.com/go/html5/launch
当然更推荐Dia画图。
还没有评论,来说两句吧...