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