ModuleLayer和ClassLoader之间是什么关系? [英] What is the relation between ModuleLayer and ClassLoader?

查看:58
本文介绍了ModuleLayer和ClassLoader之间是什么关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's consider the following situation. There are three layers.

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

Child1是BootLayer的子代,Child2是Child1的子代.

Child1 is the child of the BootLayer, Child2 is the child of the Child1.

Child1 Child2 是由相同的代码创建的:

Child1 and Child2 was created by the same code:

ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parentLayer.defineModulesWithOneLoader(cf, parentClassLoader);

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

As you see the parent class loader of both child layers is SystemClassLoader. However, moduleB can use classes of moduleA, but moduleC can use classes of moduleA and moduleB.

我是类加载的初学者,但是我已经阅读了有关 parent-first委托模型的信息.但是,如果两个子层都使用SystemClassLoader,那么为什么他们看到其他层的类呢?有人可以解释吗?

I am a beginner at classloading, but I've read about parent-first delegation model. However, if for both child layers SystemClassLoader is used, then why they see classes from other layers? Could anyone explain?

推荐答案

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

The answer was given by Alan Bateman in jigsaw-dev mailing list and is posted here.

模块层是一个高级主题.ClassLoaders也是一个高级主题.在使用模块层并使用 defineModulesWithXXX 方法创建模块层时,您通常不需要太在意类加载器.它们仍然用于加载类,但是它们大部分在后台(而不是您的脸).

Module layers are an advanced topic. ClassLoaders are also an advanced topic. When working with module layers and using the defineModulesWithXXX methods to create the module layers, then you mostly don't need to be too concerned with class loaders. They are still used to load classes but they are mostly in the background (and not in your face).

您也不必太担心为 defineOneWithOneLoader 方法指定的父类加载器".从模块加载类时不使用它,仅当 moduleB moduleC 中的代码试图加载不在模块中的类(例如> Class.forName("Foo"),其中 Foo 在类路径上.因此,可能最好在开始时忽略父类加载器.

You also don't need to be too concerned with the "parent class loader" that you specify to the defineOneWithOneLoader method. It's not used when loading classes from modules, it's only when for cases where the code in moduleB or moduleC tries to load a class that is not in a module, maybe Class.forName("Foo") where Foo is on the class path. So probably best to ignore the parent class loader when starting out.

The API docs explain how the delegation works with modules but maybe it's not clear enough for what is needed here. In your example, support L1 is the class loader for moduleB in child layer 1, and L2 is the class loader for moduleC in child layer 2. Further suppose the module declarations are:

module moduleC {
     requires moduleB;
}

module moduleB {
     exports b;
}

Child1 的配置非常简单:一个读取 java.base

Child2 的配置也非常简单:一个读取 moduleB java.base moduleC .

The configuration for Child2 is also very simple: one moduleC that reads moduleB and java.base.

创建 Child1 后,它将创建 L1 ,并将 moduleB 映射到 L1 .当 moduleB 中的代码尝试解析其自身模块中对类的引用时,它将由 L1 (无委托)加载.当 moduleB 引用 java.base 中的类时, L1 将委托给 boot loader .

When Child1 is created it will create L1 and map moduleB to L1. When code in moduleB tries to resolve a reference to a class in its own module then it will be loaded by L1 (no delegation). When moduleB references a class in java.base then L1 will delegate to the boot loader.

创建 Child2 后,它将创建 L2 ,并将 moduleC 映射到 L2 .当 moduleC 中的代码尝试解析其自身模块中对类的引用时,它将由 L2 加载(无委托).当 moduleC 引用一个 b.* 类时,它将被委托给 L1 来解析该引用.当 moduleC 在java.base中引用一个类时, L2 将委托给引导加载程序.

When Child2 is created it will create L2 and map moduleC to L2. When code in moduleC tries to resolve a reference to a class in its own module then it will be loaded by L2 (no delegation). When moduleC references a b.* class then it will be delegate to L1 to resolve the reference. When moduleC references a class in java.base then L2 will delegate to the boot loader.

如果将其绘制出来,则应该看到类加载器委托是直接委托",并且完全反映了可读性图(配置对象)中的边缘.

If you draw this out then you should see that the class loader delegation is "direct delegation" and exactly mirrors the edges in the readability graph (Configuration object).

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

Hopefully this is enough to get your started. It really needs diagrams and graphs to explain some of these details probably. As I said, you can mostly ignore class loader details when working with module layers.

这篇关于ModuleLayer和ClassLoader之间是什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆