我想了解Java类加载器的工作原理.我看过一些文章,但有些事情我还不清楚.
据我所知,第一个类加载器是Bootstrap类加载器(BCL).它是由JVM加载的吗?
然后,BCL加载rt.jar库和扩展类加载器(ECL).
反过来,ECL加载扩展和应用程序类加载器(ACL).ACL负责从类路径加载所有用户开发的类.
这种描述是否正确?
有一些问题:
答案:
据我了解,第一个类加载器是引导类加载器(BCL)。它是由JVM加载的吗?
这没有明确定义,但很可能用本机代码编写。
然后,BCL 加载 rt.jar 库和扩展类加载器 (ECL)。
是的,它将加载 rt.jar(直到 Java 8 和 Java 9 一样,会有新的模块系统)。是否加载 ECL 没有明确定义。
ECL 依次加载扩展和应用程序类加载器 (ACL)。ACL 负责从类路径加载所有用户开发的类。
是的,它会加载扩展,并且是否加载 ACL 没有明确定义。事实上,ACL 加载类路径条目。
每个类加载器在内存中只存在一个实例?(BCL、ECL、ACL)?
是的,这是正确的。由于类标识被定义为一对FQCN及其有效类加载器,否则将无法工作。
我看过委托原则,但对我来说有点不清楚。它是如何工作的,假设我们需要加载 MyClass。首先jvm将这个类名赋予ACL,这对我来说不清楚,ACL查看类路径,如果没有这样的类,则将这项工作委托给父级,或者在调用后立即将这项工作委托给父级,我的意思是JVM将类名提供给 ACL,它不会搜索该类并将其提供给 ECL,该 CL 反过来也不做任何工作并将其提供给 BCL,并且只有当 BCL 找不到该类时才将其返回给下层水平(ECL)....等等。什么是正确的链条?
在标准Java中,存在父优先委托模型,这意味着类加载器将首先询问其父类,然后才尝试自己加载类。
当我们创建自定义类加载器时,它的父类是什么?应用程序类加载器 ? 我们可以指定 ,例如 ECL 吗?由于类加载器的层次结构不是继承,我们在构造函数中指定父类。我们能否获取 ECL 类加载器的实例,以在自定义 CL 中将其指定为构造函数中的父级。
自定义类加载器的默认父级是应用程序类加载器。
问题是你为什么需要这样做?您的程序不太可能正确运行。正式地,您可以通过以下方式执行此操作YourClass.class.getClassLoader().getParent()。
为什么像 String 、 Object 等类不返回任何 ClassLoadder ?
nullBootstrap 类加载器在 API 中表示。