首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UrlClassLoader委托和继承层次结构

UrlClassLoader委托和继承层次结构
EN

Stack Overflow用户
提问于 2015-12-08 16:01:05
回答 1查看 2.4K关注 0票数 12

我被UrlClassLoader委托层次结构和继承层次结构混淆了。我创建了扩展UrlClassLoader的类,并执行了:childOfUrlClassLoader.getParent().getClass().getName(),它给了我:sun.misc.Launcher$AppClassLoader。在此之后,我访问了上述类(来源)。

代码语言:javascript
复制
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的代码有行

代码语言:javascript
复制
294    return (super.loadClass(name, resolve));

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

2)为什么ExtClassLoader没有把BootstrapClassLoader作为父母,而是有null

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-11 17:17:04

代表-first model

内置的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缓存

在实践中,每个类加载器都有一个缓存,其中已加载的类被存储,缓存在委托给父类之前被搜索,但这并不改变首先委派的原则。

这是检查缓存的地方。

代码语言:javascript
复制
Class c = findLoadedClass(name);

URLClassLoaders

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

问题

1)谁加载了我的课?

我在链接中看到了稍微不同的代码

代码语言:javascript
复制
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找到这个类。

代码语言:javascript
复制
321                 c = findClass(name);

2)为什么ExtClassLoader不以BootstrapClassLoader作为父级,而具有null?

这是由getClassLoader API回答的

getClassLoader()返回该类的类加载器。有些实现可能使用null来表示引导类加载器。

3) AppClassLoader类扩展UrlClassLoader的目的是什么?

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

参考资料

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

  • Java ClassLoading的内部构件
  • Oracle教程
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34160415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档