当前位置: 首页 > 知识库问答 >
问题:

类加载器委托模型

墨雨华
2023-03-14

我有一个简单的自定义ClassLoader

class CustomLoader extends ClassLoader {
    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        System.out.println("In the custom loader");
        throw new ClassNotFoundException();
    }
}

下面是我试图使用加载器的代码:

public static void main(String... str) throws ClassNotFoundException {
        CustomLoader loader = new CustomLoader();
        Class<?> cls = loader.loadClass("java.awt.Color");

        System.out.println(cls);
        System.out.println(cls.getClassLoader());
}

结果是相当令人期待的:

class java.awt.Color
null

在大多数文章中,您可以看到,当您在自定义加载程序上调用loadClass时,它首先尝试在其缓存中查找该类。如果找不到,则从父加载程序(在本例中为应用程序加载程序)调用loadClass方法。引导加载程序也是如此。之后,如果引导加载程序在其缓存中找不到该类,它将尝试在相应的源中找到该类。如果加载程序找不到它,子加载程序将尝试查找自定义加载程序,依此类推。

如果您查看类加载器实现,您将看到它只是调用findClass方法。但是考虑到我使用自定义加载器,并且java有多态性,无论父加载器在哪里调用findClass,他们都会调用我的方法,对吗?

同时,据说java不会一次加载所有类,而且只在必要时加载。

如您所见,我们没有看到任何类强制转换异常,事实上我的重写方法甚至没有被调用。这意味着引导加载程序发现它是类颜色。

问题是我的错误在哪里?当jvm启动时,如果java没有从java...包加载所有的类,它就不会在缓存中找到类颜色,它会调用我的重写方法。

(该类颜色未在代码中的任何其他位置使用)

共有1个答案

阮星火
2023-03-14

根据ClassLoaderAPI,默认的委托模型是这样工作的

当请求查找类或资源时,ClassLoader实例将在尝试查找类或资源本身之前,将对类或资源的搜索委托给其父类加载器。

这个委托模型是在类加载器中实现的。loadClass方法,若要更改它,应重写loadClass方法而不是findClass

 类似资料:
  • 问题内容: 调用时,首先检查该类是否已加载,还是立即将该检查委托给其父级? Java API说: 当请求查找类或资源时,ClassLoader实例会将对类或资源的搜索委托给其父类加载器,然后再尝试查找类或资源本身。 但是在《 Java Reflection in Action》 一书中有一章关于类加载器的特定章节说: 类加载器调用findLoadedClass来检查该类是否已经加载。如果类加载器找

  • 1.1 加载 将字节码数据从各种不同的数据源(class 文件、jar 文件等)中读到 JVM 中,映射为 Java 认可的数据结构(Class 对象)。 1.2 连接 验证:过滤掉不合法的 class 文件。 准备:为静态变量分配内存,此时不进行实例化,采用默认值。 解析: 1.3 初始化为静态变量赋予正确的初始值。 2. 类加载器类型 启动类加载器 扩展类加载器 应用类加载器 自定义类加载器

  • 生成器委托 PHP7中支持delegating generator,可以自动展开subgenerator; A “subgenerator” is a Generator used in the portion of the yield from syntax. 我们需要在PHP5支持子生成器,将子生成器最后yield值作为父生成器yield表达式结果,仅只需要加两行代码,递归的产生一个Async

  • 我曾经读到过Java中类装入器的委托模型的“唯一性”特性: https://www.baeldung.com/java-classloaders#uniqueness 我不明白,如果没有这样的模型,我们怎么会有加载非唯一类的风险呢? 当类装入器使用完全限定的类名来装入它们时,我们如何才能最终装入重复的类,特别是当我们在将任务委托给父装入器之前检查一个类是否已经装入时? https://www.ba

  • 主要内容:类委托,属性委托,标准委托,可观察属性 Observable,把属性储存在映射中,Not Null,局部委托属性,属性委托要求,翻译规则,提供委托委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。 Kotlin 直接支持委托模式,更加优雅,简洁。Kotlin 通过关键字 by 实现委托。 类委托 类的委托即一个类中定义的方法实际是调用另一个类的对象的方法来实现的。 以下实例中派生类 Derived 继承了接口

  • 主要内容:声明委托,实例化委托,多播委托(合并委托)C# 中的委托(Delegate)类似于 C 或 C++ 中的函数指针,是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。委托特别适用于实现事件和回调方法,所有的委托都派生自 System.Delegate 类。在实例化委托时,可以将委托的实例与具有相同返回值类型的方法相关联,这样就可以通过委托来调用方法。另外,使用委托还可以将方法作为参数传递给其他方法, 委托具有以下特点: 委托类似