java中的类加载器本身就是一个类,那么谁将加载类加载器类?
Java中的ClassLoader是一个用于加载Java中的类文件的类。
java.lang.ClassLoader是一个抽象类
这里我的问题是这个java.lang.ClassLoader类是否与JVM的类加载器有关(1. Bootstrap类加载器2.扩展类加载器3.系统类加载器)?
或者这个java.lang.ClassLoader是一个独立的类,可以用来创建一个自定义类加载器?
类加载器是将Java类动态加载到Java虚拟机中的Java运行时环境的一部分。 它负责定位库,读取内容并加载库中包含的类当JVM启动时,使用三个类装载器
引导类加载器
扩展类加载器
系统类加载器
引导类加载器加载核心Java库。 它是用本地代码编写的。 引导类加载器负责将关键java类(如java.lang.Object和其他运行时代码)加载到内存中。 运行时类被封装在jre / lib / rt.jar文件中。
扩展类加载器将代码加载到扩展目录中。 它由ExtClassLoader类实现。
系统类加载器在java.class.path中找到的代码映射到系统类路径变量。 它由AppClassLoader类实现。 所有的用户类默认都是由系统类加载器加载的。
Java ClassLoader是分层的,每当引发一个请求来加载一个类时,它就会将它委派给它的父代,并以这种方式在运行时环境中保持唯一性。 如果父类加载器没有找到该类,那么类加载器本身会尝试加载该类。
所以这意味着第一个系统类加载器将请求委托给扩展类加载器,它将请求委托给引导类加载器,在这里它将搜索类,如果没有找到,那么扩展类加载器将搜索类,如果没有找到,则系统类加载器将搜索类如果没有找到,则抛出ClassNotFoundException
JVM是否始终以加载类的System类加载器开始?
纠正我,如果我错了任何地方
术语“系统类加载器”是不恰当的。 正如您所说的那样,它负责从类路径的位置(它们是应用程序类)加载类。
从Java 8开始, AppClassLoader
和ExtClassLoader
都是java.net.URLClassLoader
的子类,它是java.security.SecureClassLoader
的子类,它是java.lang.ClassLoader
的子类。 所有这些类都由Bootstrap加载器加载,解决鸡与蛋问题。
每个运行时类都有一个定义类加载器。 对于在启动过程中由Bootstrap加载器定义的类,定义的类加载器是Bootstrap加载器。 当JVM初始化完成并尝试启动应用程序时,将为主类查询Application类加载器(又名System类加载器)。 Application类加载器将首先遵循标准委托模型查询父类,同样,Extension类加载器和哪个类加载器将创建该类将是类的定义类加载器。
现在,在解析由另一个类引用的类或调用Class.forName(String)
,将使用包含引用的类的定义加载器来解析该类。 因此,当Application类加载器加载了您的类myapp.foo.Bar
并且它包含对javax.swing.JButton
的引用时,将会为它的定义类加载器(即Application类加载器)查询该类,请遵循委派模型最终得到由Bootstrap加载器定义的javax.swing.JButton
。 因此, javax.swing.JButton
中的类引用仅通过Bootstrap加载程序解析,这意味着javax.swing.JButton
不能包含对myapp.foo.Bar
类的引用,因为它不在范围内。
因此,JVM并不总是以“系统类加载器”开始加载一个类,而只是用于解析由它定义的类的类引用(或者一个子加载器),或者当被显式查询时(比如解析主类时)。
有些第三方类加载器并不严格遵循父代理模型,但是不管他们如何以及他们委派哪个加载器,每个类(由getClassLoader()
返回的加载器)都将有一个定义加载器,这将是使用的加载器用于解决课程中的参考。 JVM确保一个类中的相同符号名称始终解析为相同的运行时类,而不管特定的类加载器如何实现查找。
请注意,在Java 9中,扩展类加载器已被平台类加载器取代。 这个类加载器可能会偏离简单的父代理,也就是说,它可能委托给Application类加载器来加载应用程序提供的模块,这些模块将取代平台提供的模块。 此外,内置类加载器不再是URLClassLoader
子类。
上一篇: classloader in java is a class itself then who will load the classloader class?