gpt4 book ai didi

java - ModuleLayer 和 ClassLoader 有什么关系?

转载 作者:行者123 更新时间:2023-12-04 01:30:10 24 4
gpt4 key购买 nike

让我们考虑以下情况。共有三层。

BootLayer (moduleA)
|
|_______Child1(moduleB)
|
|__________ Child2(moduleC)

Child1 是 BootLayer 的 child ,Child2 是 Child1 的 child 。
Child1Child2由相同的代码创建:
ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parentLayer.defineModulesWithOneLoader(cf, parentClassLoader);

如您所见,两个子层的父类加载器都是 SystemClassLoader。但是, moduleB可以使用 moduleA 的类, 但是 moduleC可以使用 moduleA 的类和 moduleB .

我是类加载的初学者,但我读过 parent-first delegation model .但是,如果两个子层都使用 SystemClassLoader,那么为什么他们会看到其他层的类?谁能解释一下?

最佳答案

答案由 Alan Bateman 在 jigsaw-dev 邮件列表中给出,并发布在此处。

模块层是一个高级主题。类加载器也是一个高级主题。当使用模块层和使用 defineModulesWithXXX方法来创建模块层,那么你大多不需要太关心类加载器。它们仍然用于加载类,但它们大多在后台(而不是在你的脸上)。

你也不需要太关心你指定给 defineOneWithOneLoader 的“父类加载器”。方法。从模块加载类时不使用,仅用于 moduleB 中的代码的情况或 moduleC尝试加载不在模块中的类,可能是 Class.forName("Foo")在哪里 Foo在类路径上。所以可能最好在开始时忽略父类加载器。

API docs解释代表团如何与模块一起工作,但对于这里需要什么可能还不够清楚。在您的示例中,支持 L1moduleB 的类加载器在子层 1 和 L2moduleC 的类加载器在子层 2。进一步假设模块声明是:

module moduleC {
requires moduleB;
}

module moduleB {
exports b;
}
Child1 的配置很简单:一个 moduleB显示为 java.base Child2 的配置也很简单:一个 moduleC显示为 moduleBjava.base .

Child1已创建它将创建 L1和 map moduleBL1 .当代码在 moduleB尝试解析对自己模块中的类的引用,然后它将被 L1 加载(无授权)。当 moduleB引用 java.base 中的一个类然后 L1将委托(delegate)给 boot loader .

Child2已创建它将创建 L2和 map moduleCL2 .当代码在 moduleC尝试解析对自己模块中的类的引用,然后它将被 L2 加载(无授权)。当 moduleC引用 b.*类,那么它将被委托(delegate)给 L1解决引用。当 moduleC引用 java.base 中的一个类,然后 L2将委托(delegate)给引导加载程序。

如果你把它画出来,那么你应该看到类加载器委托(delegate)是“直接委托(delegate)”,并且完全反射(reflect)了可读性图(配置对象)中的边缘。

希望这足以让你开始。它确实需要图表来解释其中一些细节。正如我所说,在使用模块层时,您几乎可以忽略类加载器的详细信息。

关于java - ModuleLayer 和 ClassLoader 有什么关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61195909/

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