java - 类加载器 : Delegation Hierarchy Algorithm

标签 java

众所周知,类加载器子系统使用“委托(delegate)层次结构算法”来加载类。我很想了解其实现背后的行为或逻辑。即,即使该类存在于当前目录中(应用程序/系统类加载器可能知道它),“引导带加载器”仍然获得优先级并将其委托(delegate)给其子级。难道就不能改变或者改进吗?

最佳答案

理论上,你可以改变这种行为,但可能会出现非常非常奇怪的问题。

假设您有多层类加载器:

例如你的类加载器 -> 一些父类加载器(例如 webapp 容器类加载器) -> system+bootsrap 类加载器。

现在你的代码尝试从 guava 加载 ImmutableMap,并且 guava.jar 对于“你的类加载器”和“webapp 容器类加载器”都是可见的。

您决定不委托(delegate),而是自行加载。这就是您获取 ImmutableMap 实例的方式。另一方面,不知何故,“webapp 容器类加载器”也从他自己的 guava.jar 文件加载了他自己的 ImmutableMap - 因为那时他无法访问“你的类加载器”,唯一的方法就是自己加载丢失的东西。

现在你有两个 ImmutableMap 类,它们被认为是不同的(因为由不同的类加载器加载),并且如果你从不同版本的 guava.jar 加载它们,它们可能会非常不同。但到目前为止,这仍然是“好的”。 当您尝试将 ImmutableMap 类的实例跨越边界传递给 web 应用程序代码时,就会发生 hell 般的情况 - 这就是 ClassCastException 发生的地方,并显示一条奇怪的消息“ImmutableMap 类无法转换为 ImmutableMap”。

为避免这种情况,请始终先调用父类加载器。

如果您 100% 确定该类的对象实例永远不会传递给使用不同类加载器加载的类 - 那么您是安全的 - 但您永远不能 100% 确定。

一些框架相关的类加载器不委托(delegate)(例如 Jboss,也许还有一些 SpringBoot 神奇类),但它们完全知道自己在做什么。

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

相关文章:

java - 我应该从 Java 编程转向 Delphi 编程吗?

处理数字的java逻辑问题

Java Process Builder 重定向输出在 Eclipse 中工作,而不是作为 jar

java - 阻塞线程运行 SAX 解析器

java - ActionPerformed 返回变量

netbeans - 未找到符号,但已导入库

java - 如何使 DatePickerDialog 的 setMinDate 与 "setCurrentDate"不同?

java - 调用模拟的私有(private)方法而不是被模拟

Java AES 256 安全 key 生成器 - 非法 key 大小

java - 如何使用 StringBuilder 和 Array 将字符串转换为二进制并反转?