gpt4 book ai didi

java - 疯狂的类加载器问题

转载 作者:行者123 更新时间:2023-11-29 06:20:03 25 4
gpt4 key购买 nike

类:

public interface Inter {
...some methods...
}

public class Impl implements Inter {
...some implementations...
}

问题是,出于某种奇怪的原因,我必须使用 child ClassLoader 加载接口(interface) Inter 并使用 Impl 加载实现类 < strong>parent 类加载器。

在这种情况下,我会得到 NoClassDefError,因为试图加载实现 Impl 的父 ClassLoader 不知道接口(interface) Inter 在子 ClassLoader 中加载。

有没有办法用子类加载器(上下文类加载器)加载实现?或者我可能需要编写一些自定义 ClassLoader 来加载它们(通过打破委托(delegate)规则)?

最佳答案

The issue is that for some freaky reason, I have to load the interface Inter with child ClassLoader and the implementation class Impl with parent ClassLoader.

我不明白为什么子类加载器必须加载接口(interface),而让父类加载器加载实现。这必然会引起麻烦,因为在 JVM 使用的类加载机制中没有任何机制可以将类加载延迟到子类加载器。在 JVM 中实现类加载行为的常用机制定义在 ClassLoader 类的 API 文档中:

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.

可以通过扩展 ClassLoader class 来编写自定义类加载器并覆盖 loadClass() method .扩展此方法允许您以两种方式之一更改类加载委托(delegate):

  • Parent-first:让父类加载器先加载类。这通常是一种传递行为——大多数父类加载器将延迟加载到它们的父类,依此类推,直到在类加载器层次结构中到达引导类加载器(根)。如果父类加载器加载类失败,则子类加载器尝试加载它。加载类的最终失败应导致抛出 ClassNotFoundException。
  • Parent-last:自定义类加载器尝试先加载类,然后再委托(delegate)给父级。仅当子类加载器尝试加载类失败时才使用父类加载器。

大多数类加载器都是作为父优先类加载器实现的。这是因为委托(delegate)机制可以向上遍历树,但不能向下遍历树。

如果您真的希望将类的加载和查找委托(delegate)给层次结构中的子类加载器,则必须在父级的自定义类加载器中管理对它们的引用。这并不容易,而且通常根本不会这样做,除非非常特殊的情况,因为很容易以可怕的 ClassNotFoundException 和 NoClassDefFoundError 结束,因为必须小心只从子类加载器加载所需的类,而其余的则必须总是被推迟到父级(除非我弄错了,某些 Java EE 容器中共享库的特性是通过这种方式实现的)。

话虽如此,理想的解决方案是尝试在父类加载器中加载接口(interface)和实现类,并依靠委托(delegate)机制来确保类对两个类加载器都可见;父级可以“看到”自己加载的类,子级可以“看到”父级的类。

PS:不要忘记使用 AccessController.doPrivileged在加载和定义类时。

关于java - 疯狂的类加载器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3509866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com