Java虚拟机(JVM)-- 类加载器和双亲委派机制
Posted Z && Y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java虚拟机(JVM)-- 类加载器和双亲委派机制相关的知识,希望对你有一定的参考价值。
1. 类加载器和双亲委派机制
1.1 类加载器的作用
类加载器的作用是加载类文件到内存
类是模板,对象是具体的,类模板唯一,对象不唯一
1.2 类加载器测试
代码:
package packge01;
/**
* @author TianJiao
*/
public class Person {
public static void main(String[] args) {
Person person01 = new Person();
Person person02 = new Person();
System.out.println("对象是不唯一的(new)");
System.out.println("person01.hashCode(): " + person01.hashCode());
System.out.println("person02.hashCode(): " + person02.hashCode());
System.out.println("---------------------------------------------");
System.out.println("模板是唯一的(Class)");
System.out.println("person01.getClass().hashCode(): " + person01.getClass().hashCode());
System.out.println("person02.getClass().hashCode(): " + person02.getClass().hashCode());
}
}
运行结果:
1.3 类记载器的类型
- 1.启动类(根)加载器(Bootstrap)
- 2.扩展类加载器 (Ext)
- 3.应用程序加载器 (App)
1.4 双亲委派机制
Java去除了C++繁琐的指针和内存管理(全在JVM)里面,所有Java又被叫做C++--
- 1.类加载器收到类加载的请求!
- 2.将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器
- 3.启动加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载
- 4.重复步骤3
class Not Found ~(.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理会先检查自己是否已经加载过,如果没有再往上。注意这个过程,知道到达Bootstrap classLoader之前,都是没有哪个加载器自己选择加载的。如果父加载器无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。)
null : java调用不到~C、C++(Java底层是C、C++写的)
委托模型机制的工作原理很简单:当类加载器需要加载类的时候,先请示其Parent(即上一层
加载器)在其搜索路径载入,如果找不到,才在自己的搜索路径搜索该类。这样的顺序其实就
是加载器层次上自顶而下的搜索,因为加载器必须保证基础类的加载。之所以是这种机制,
还有一个安全上的考虑:如果某人将一个恶意的基础类加载到jvm,委托模型机制会搜索其父
类加载器,显然是不可能找到的,自然就不会将该类加载进来。(这种设计有个好处是,如
果有人想替换系统级别的类:String.java。篡改它的实现,在这种机制下这些系统的类已经被
Bootstrap classLoader加载过了(为什么?因为当一个类需要加载的时候,最先去尝试加载
的就是BootstrapClassLoader),所以其他类加载器并没有机会再去加载,从一定程度上防
止了危险代码的植入。
测试:
package packge01;
/**
* @author TianJiao
*/
public class Person {
public static void main(String[] args) {
Person person01 = new Person();
System.out.println(person01.getClass().getClassLoader());// App
System.out.println(person01.getClass().getClassLoader().getParent());// Ext
System.out.println(person01.getClass().getClassLoader().getParent().getParent());// null (Java底层是C,C++写的)
}
}
运行结果:
验证Java底层是C、C++写的
以上是关于Java虚拟机(JVM)-- 类加载器和双亲委派机制的主要内容,如果未能解决你的问题,请参考以下文章