通俗理解JVM系列(二)——类加载机制
一.类的生命周期
加载
将.class文件从磁盘读取到内存中
连接
- 验证:验证字节码文件正确性
- 准备:给静态变量分配内存,并赋予默认值(比如int默认为0)
- 解析:类装载器装入类所引用的其他类
初始化
为类的静态变量赋予正确的初始值,用户设置的值将替换虚拟机默认的初始值
二.类加载机制的种类
1)加载器
启动类加载器
Bootstrap ClassLoader:负责加载jre核心类库,比如jdk1.8.0_221\jre\lib下的rt.jar、charsets.jar等
拓展类加载器
Extension ClassLoader:负责加载jre拓展目录ext中的jar类包,比如jre1.8.0_221\lib\ext
系统类加载器
Application ClassLoader:负责加载ClassPath路径下的类包
自定义加载器
User ClassLoader:负责加载用户自定义路径下的类包
2)加载机制
全盘负责委托机制
当一个ClassLoader加载一个类时,该类所依赖的其他引用类也由这个ClassLoader载入,除非指定使用另一个ClassLoader。
双亲委派机制(父类委派机制)
概念:类加载器收到类加载请求后,会把这个请求往上委托,每一层都是如此,直到递归到顶层。当父类无法加载这个请求时,就会下沉到子类去判断是否能加载,依次递归。一直到最底层都没有任何加载器能够加载的话,那就会抛出异常。
通俗理解:简单的说,就是当用户定义了一个类,在这个类加载的时候,系统会利用各种类加载器轮流查找一遍当前系统,看是否存在完全相同的一个类。如果没有,就运行,反之则抛出异常。
好处:这样设计,可以避免系统的顶级类被恶意篡改,比如:Object、String等,如果自定义了相同的类,就会发现在向上递归的过程中,启动类加载器(Bootstrap ClassLoader)找到了系统自带的java.lang包下有这样的类,那就抛出异常,而不会去加载篡改的同名类了。这从一定程度上防止了危险代码的植入。