当前位置:  开发笔记 > 编程语言 > 正文

UrlClassLoader委托和继承层次结构

如何解决《UrlClassLoader委托和继承层次结构》经验,为你挑选了1个好方法。

我对UrlClassLoader委派层次结构和继承层次结构感到困惑.我创建了扩展UrlClassLoader并执行的类:childOfUrlClassLoader.getParent().getClass().getName() 它给了我: sun.misc.Launcher$AppClassLoader.在此之后我访问了上面提到的类(来源)

249 static class AppClassLoader extends URLClassLoader {
        //...
308     protected synchronized Class loadClass(String name, boolean resolve)
309         throws ClassNotFoundException
310     {
311         // First, check if the class has already been loaded
312         Class c = findLoadedClass(name);
313         if (c == null) {
314             try {
315                 if (parent != null) {
316                     c = parent.loadClass(name, false);
317      
          // ...
329         return c;
330     }

然后我检查了谁是AppClassLoader的父级.我得到sun.misc.Launcher$ExtClassLoader了ExtClassLoader的父母null.


我有几个问题:

1)自从AppClassLoader.loadClass有行代码以来,谁加载我的类

294    return (super.loadClass(name, resolve));

它看起来像循环,不是吗?

2)为什么ExtClassLoader不BootstrapClassLoader作为父级,但有null

3)为什么AppClassLoader类扩展了UrlClassLoader?



1> Neil Masson..:

代表优先模型

内置的Java ClassLoaders遵循委托优先模型.这意味着ClassLoader将允许其父级在尝试加载类之前加载它.加载器的层次结构在顶部有引导加载程序,后跟扩展类加载器,即应用程序类加载器.在应用程序类下,可以找到URLClassLoaders和应用程序创建的任何其他加载器.

引导类加载器可以从rt.jar加载文件,其中包含最基本的java类,包括java.lang,java.io,java.util和java.net包中的类.扩展类加载器从java安装中的其他jar文件加载类.它是应用程序类加载器,它加载类路径中找到的类,并且是应用程序启动时的当前类加载器.

正在加载行动

那么当应用程序想要加载HashMap时会发生什么?要求当前的类加载器加载HashMap类.在尝试任何事情之前,它会询问其父级,扩展类加载器加载该类.反过来,扩展类加载器继承到引导类加载器,它在rt.jar中查找类并加载它.

如果要加载的类在类路径中,请求将像以前一样上传到引导类加载器以检查rt.jar.引导加载程序无法找到该类,因此该任务将返回到扩展类加载器,该类加载器在java安装中搜索该类.当此操作失败时,任务将恢复为应用程序类加载器,该类加载器将扫描类的类路径.

ClassLoader缓存

实际上,每个类加载器都有一个缓存,其中存储了已加载的类,并在委托给父代之前搜索缓存,但这并不会改变委托的原则.

这是检查缓存的位置

Class c = findLoadedClass(name);

URLClassLoaders

由应用程序创建的URLClassLoader将应用程序ClassLoader作为父级.如果它遵循委托优先模型,则在提供的URL之前的类路径中将找到类.

问题

1)谁加载我的课程

我看到链接中的代码略有不同

309         // First, check if the class has already been loaded
310         Class c = findLoadedClass(name);
311         if (c == null) {
312             try {
313                 if (parent != null) {
314                     c = parent.loadClass(name, false);
315                 } else {
316                     c = findBootstrapClass0(name);
317                 }
318             } catch (ClassNotFoundException e) {
319                 // If still not found, then invoke findClass in order
320                 // to find the class.
321                 c = findClass(name);
322             }
323         }

如果父类没有加载类,它会抛出一个被捕获的ClassNotFoundException,并允许当前的ClassLoader查找该类

321                 c = findClass(name);

2)为什么ExtClassLoader没有BootstrapClassLoader作为父级,但是为空?

这可以通过getClassLoader API来解决

[getClassLoader()]返回类的类加载器.某些实现可能使用null来表示引导类加载器.

3)为什么AppClassLoader类扩展了UrlClassLoader?

考虑到应用程序类加载器并不特殊,因为它加载了用户提供的类,而不是系统类.类路径实际上是一个URI列表,因此URLClassLoader是一个合适的超类.

参考

关于类加载的文章很多,包括

Java ClassLoading的内部结构

Oracle教程

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有