之所以这个东西面试出场概率高高,最大的原因就是它起的名字很好听
描述了查找 .class
文件的策略。
JVM
中进行类加载的操作,是有一个专门的模块,称为“类加载器”(ClassLoader
)。JVM
中的类加载器默认是由三个(也可以自定义个数)
类加载器的作用,给它一个“权限定类名”(带有包的类名(java. lang. String
)),给了之后,就找到对应的 .class
文件。这里的类加载器就是从不同的目录中进行查找
BootstrapClassLoader
ExtensionClassLoader
Java
语法的规范里面描述了标准库中应该有哪些功能。实现 JVM
的厂商/组织会在标准库的基础上扩充一些额外的功能(JVM
内置的,不同的厂商扩展的可能不太一样)ApplicationClassLoader
上述的三个类加载器,存在“父子关系”
parent
,指向自己的“父”类加载器双亲委派模型,就描述了上述类加载器之间是符合配合工作的
双亲委派模型工作过程:
ApplicationClassLoader
作为入口,先开始工作
ApplicationClassLoader
不会立即搜索自己负责的目录,会把搜索的任务交给自己的父亲
ExtensionClassLoader
范畴了,但它也不会立即搜索自己负责的目录,也要把搜索的任务交给自己的父亲
BootstrapClassLoader
范畴了,它也不想立即搜索自己负责的目录,也想把搜索的任务交给自己的父亲
BooststracpClassLoader
发现自己没有父亲,才会真正搜索负责的目录(标准库目录),通过全限定类名,尝试在标准库目录中找到符合要求的 .class
文件
ExtensionClassLoader
收到父亲交回给他的任务之后,自己进行搜索负责目录(扩展库的目录)
ApplicationClassLoader
收到父亲交回给他的任务之后,自己进行搜索负责的目录(当前项目目录/第三方库目录)
ApplicationClassLoader
没有孩子了,此时说明类加载过程失败了,就会抛出 ClassNotFoundException
异常上述设定的最主要的目的就是为了确保这几个类加载器之间的优先级
按照上述的顺序,假定在代码中自己定义了一个 java.lang.String
这样的类。最终程序执行效果是:自定义的类不会被 JVM
加载
BootstrapClassLoader
到标准库中找,就找到了这个类,直接就从标准库中加载了,就不会回到 ApplicationClassLoader
(你自己写的代码中)这一层进行加载
设定就是为了避免你写的类的名字和标准库的重复了,导致标准库的类的功能失效