- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我对 UrlClassLoader 委托(delegate)层次结构和继承层次结构感到困惑。我创建了扩展 UrlClassLoader 的类并执行了:childOfUrlClassLoader.getParent().getClass().getName()
这给了我:sun.misc.Launcher$AppClassLoader
。之后我访问了上面提到的类(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
。
我有几个问题:
1) 因为 AppClassLoader.loadClass
的代码有行,谁来加载我的类
294 return (super.loadClass(name, resolve));
它看起来像循环,不是吗?
2) 为什么 ExtClassLoader 没有 BootstrapClassLoader
作为父级,而是有 null
?
3) AppClassLoader 类扩展 UrlClassLoader 的目的是什么?
最佳答案
委托(delegate)优先模型
内置的 java 类加载器遵循委托(delegate)优先模型。这意味着 ClassLoader 将允许其父类在尝试自己加载类之前加载它。加载器的层次结构在顶部是引导加载器,然后是扩展类加载器,即应用程序类加载器。在应用程序类加载器下可以找到 URLClassLoaders 和应用程序创建的任何其他加载器。
引导类加载器可以从 rt.jar 加载文件,其中包含最重要的 java 类,包括 java.lang、java.io、java.util 和 java.net 包中的类。扩展类加载器从 java 安装中的其他 jar 文件加载类。应用程序类加载器加载在类路径中找到的类,并且是应用程序启动时的当前类加载器。
正在加载
那么当应用程序想要加载一个 HashMap 时会发生什么?当前的类加载器被要求加载 HashMap 类。在尝试任何事情之前,它会询问其父类,即扩展类加载器来加载该类。反过来,扩展类加载器委托(delegate)给引导类加载器,引导类加载器在 rt.jar 中找到类并加载它。
如果要加载的类在类路径中,请求将像以前一样转到引导类加载器以检查 rt.jar。引导加载程序找不到该类,因此该任务被返回到扩展类加载器,该扩展类加载器在 java 安装中搜索该类。当这失败时,任务恢复到扫描类路径的应用程序类加载器。
类加载器缓存
在实践中,每个类加载器都有一个缓存,其中存储了已加载的类,并且在委托(delegate)给父级之前搜索缓存,但这不会改变先委托(delegate)的原则。
这里是检查缓存的地方
Class c = findLoadedClass(name);
URLClassLoaders
应用程序创建的 URLClassLoader 将应用程序 ClassLoader 作为父级。如果它遵循委托(delegate)优先模型,将在提供的 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 作为父级,而是有 null?
这由 getClassLoader API 回答
[getClassLoader()] returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader.
3) AppClassLoader 类扩展 UrlClassLoader 的目的是什么?
考虑到应用程序类加载器并不特殊,因为它加载的是用户提供的类,而不是系统类。类路径实际上是一个 URI 列表,因此 URLClassLoader 是一个合适的父类(super class)。
引用资料
有很多关于类加载的文章,包括
关于java - UrlClassLoader 委托(delegate)和继承层次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34160415/
我想使用 URLClassLoader 从 jar 存档中加载特定目录中的类。 项目结构如下 / application.jar /lib/ mysql.jar log4j.jar .
我在一个目录中有多个来自不同包的已编译 Java 类文件,如下所示。 C:/classes/package/A.class C:/classes/package/B.class C:/classes/
我正在使用 URLClassLoader 从外部 jar 文件加载类,由此加载的类可能已经存在于我的 Web 应用程序类加载器中,假设 URL 类加载器已加载版本 1 的类 A 和 Web 应用程序使
我想在目录 F:/badge-dao/bin/com/badge/dao/impl/ 中加载一个名为 BadgeDaoImpl 的文件。我正在编写和测试以下代码。 如果我更改目录或类名,它会抛出异常。
我编写了一个程序来管理以 jar 形式提供的插件。 我使用 URLClassLoader 加载插件类,它按预期工作。我添加了一些存储在插件 jar 中的资源(XML 文件)。 如果我调用不使用资源的方
在我之前的问题中,我询问了如何加载远程 jar 文件。我当前的代码是这样的: //f is the path to the jar URLClassLoader loader = new URLCla
我有一个非常奇怪的问题。 我正在使用 URLClassLoader 从目录中动态导入文件。如果我使用文字字符串,代码可以正常工作,如果我将变量用于文字字符串,代码也可以正常工作,但这不是我需要的。 p
我有相当简单的场景: 我的应用程序具有包含我的应用程序逻辑的核心 jar 文件。这个核心 jar 应该在运行时动态监视文件夹,当插件 jar 被放到那里时,它应该加载它并准备好使用它。可能有很多插件j
所以我正在制作一个服务器,很像 IRC,只是为了了解更多信息,这就是我的问题。 我有每个人都可以根据自己的权限调用的命令,并且每个“命令”都有自己的类,所有类都位于一个目录中。我将所有类加载到 Has
我在互联网上浏览了很多 URLClassLoader 内存泄漏解决方案,但我还没有找到任何完全工作的代码和精确的解决方案。我找到的最接近的解决方案是 this 任何功能齐全的代码或链接,它使用 Wea
我有一个相当复杂的 Java 软件,它必须动态加载一个类、创建一个对象并调用其方法之一。事实证明,在某些情况下,如果加载的类引用了另一个类,则会引发 NoClassDefFoundError(由 Cl
这是我的代码: File folder = /* the folder with a.txt file */ final URL[] urls = new URL[] { folder.toURI
在开发一个 ant 任务以使用注释为项目自动生成一些 gui 代码时,因为我更喜欢声明性方法,所以我使用 java.net.URLClassLoader动态添加类到我的类路径。 当扫描类的类级别注释时
我正在尝试编写一段在运行时动态加载类的代码 public class URLDynClassLoader { public URLDynClassLoader(){ try{
我有一个 java 项目,它使用 URLClassLoader 在运行时从另一个 jar 文件加载类,就像插件系统一样。让我给你一个简化版本的问题:假设在我的 main 方法中,我将创建 ClassL
所以我知道如何使用 URLClassLoader,并且我知道它的作用,我想知道它到底是如何做到的。 基本上我在问:这是直播吗?或者它会临时下载并在本地读取类吗? 因此,如果您不断地从使用 URLCla
我有以下代码片段 URL url = new File("c:/work/projects/jars/").toURI().toURL(); URL[] urls = new URL[]{url};
在哪种情况下,可以使用 URLClassLoader 从指定路径中的特定 jar 加载类? 例如。 URL url = new URL("file:///path/to/customClasses.j
假设我正在创建一些加载外部目录中所有 jar 的东西,以动态向应用程序添加可选功能。 我迭代该目录中的所有 jar 并确认它们是 jar 并将它们作为 URL 加载到 URLCLassLoader 中
我正在尝试编写一个可以从命令行传递任意文件的 Java 1.7 应用程序。该文件将被添加到类加载器中,以便可以将其用作资源。 将文件添加到 URLClassLoader 似乎可行,但是添加到 Clas
我是一名优秀的程序员,十分优秀!