UrlClassLoader委派和继承层次结构 [英] UrlClassLoader delegation and inheritance hierarchy

查看:72
本文介绍了UrlClassLoader委派和继承层次结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直对UrlClassLoader委托层次结构和继承层次结构感到困惑.我创建了扩展UrlClassLoader的类并执行: childOfUrlClassLoader.getParent().getClass().getName()这给了我: sun.misc.Launcher $ AppClassLoader .之后,我访问了上述课程(

I have been confused with UrlClassLoader delegation hierarchy and inheritance hierarchy. I created class that extends UrlClassLoader and executed: childOfUrlClassLoader.getParent().getClass().getName() which gave me: sun.misc.Launcher$AppClassLoader. After this I pay a visit to mentioned above class (source)

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 .

Then I checked who is a parent of AppClassLoader. Expectedly I got sun.misc.Launcher$ExtClassLoader and the parent of ExtClassLoader is null.

我有几个问题:

1)谁加载了我的课程,因为 AppClassLoader.loadClass 的代码有一行

1) Who loads my class since the code of AppClassLoader.loadClass has line

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

看起来像循环,不是吗?

It looks like loop, doesn't it?

2)为什么ExtClassLoader没有以 BootstrapClassLoader 作为父项,却没有 null ?

2) Why doesn't ExtClassLoader have BootstrapClassLoader as a parent, but has null?

3)出于什么目的,AppClassLoader类扩展了UrlClassLoader?

3) For which purpose AppClassLoader class extends UrlClassLoader?

推荐答案

委托优先模型

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

The build-in java ClassLoaders follow a delegate-first model. This means that a ClassLoader will allow its parent to load a class before it tries to load it itself. The hierarchy of loaders has the bootstrap loader at the top, followed by the extension classloader, the application classloader. Under the application classloader can be found URLClassLoaders and any other loaders created by the application.

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

The bootstrap classloader can load files from rt.jar which contains the most essential java classes including those in the java.lang, java.io, java.util and java.net packages. The extension classloader loads classes from other jar files in the java installation. It is the application classloader which loads the classes found on the classpath and which is the current classloader when an application starts.

正在加载

那么,当应用程序要加载HashMap时会发生什么?要求当前的类加载器加载HashMap类.在尝试任何操作之前,它要求其父级(即扩展类加载器)加载该类.反过来,扩展类加载器会委托给引导类加载器,该引导加载器会在rt.jar中找到该类并进行加载.

So what happens when an application wants to load a HashMap? The current classloader is asked to load the HashMap class. Before attempting anything, it asks its parent, the extension classloader to load the class. In turn the extension classloader delgates to the bootstrap classloader which finds the class in rt.jar and loads it.

如果要加载的类在类路径中,则该请求将像以前一样转到引导类加载器,以检查rt.jar.引导加载程序找不到该类,因此该任务被引回到扩展类加载程序,该扩展程序在Java安装程序中搜索该类.如果失败,该任务将返回到应用程序类加载器,后者会扫描该类的类路径.

If the class to be loaded is in the classpath, the request goes up to the bootstrap classloader as before to check rt.jar. The bootstrap loader fails to find the class, so the task is referred back to the extension classloader which searches the java installation for the class. When this fails the task reverts back to the application classloader which scans the classpath for the class.

ClassLoader缓存

在实践中,每个类加载器都有一个高速缓存,用于存储已加载的类,并在委派给父级之前先搜索该高速缓存,但这不会改变首先委派的原理.

In practice each classloader has a cache where classes already loaded are stored and the cache is searched before the delegation to the parent, but this does not alter the principle of delegating first.

这是检查缓存的地方

Class c = findLoadedClass(name);

URLClassLoaders

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

A URLClassLoader created by an application will have the application ClassLoader as a parent. If it follows the delegate-first model, classes will be found in the classpath before the supplied URL.

问题

1)谁加载了我的课程

1) Who loads my class

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

I see slightly different code in your link

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查找该类

If a class is not loaded by the parent, it throws a ClassNotFoundException which is caught and allows the current ClassLoader to find the class

321                 c = findClass(name);

2)为什么ExtClassLoader不能将BootstrapClassLoader作为父级,却具有null?

2) Why doesn't ExtClassLoader have BootstrapClassLoader as a parent, but has null?

getClassLoader API 对此进行了回答.

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

[getClassLoader()] returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader.

3)AppClassLoader类出于什么目的扩展了UrlClassLoader?

3) For which purpose AppClassLoader class extends UrlClassLoader?

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

Consider that the application classloader is not special in that it loads classes supplied by the user, not system classes. The classpath is effectively a list of URIs so a URLClassLoader is a suitable superclass.

参考

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

There are many article on classloading including

这篇关于UrlClassLoader委派和继承层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆