java中的classloader是一个类本身然后谁将加载类加载器类?

时间:2017-11-16 02:33:23

标签: java jvm classloader

Java中的ClassLoader是一个用于在Java中加载类文件的类。

java.lang.ClassLoader是一个抽象类

这里我的问题是这个java.lang.ClassLoader类是否与JVM的类加载器有关(1.Bootstrap类加载器2.扩展类加载器3.系统类加载器)?

或者这个java.lang.ClassLoader是一个单独的类,可以用来创建自定义类加载器吗?

类加载器是Java运行时环境的一部分,它将Java类动态加载到Java虚拟机中。它负责定位库,读取内容并加载库中包含的类。当JVM启动时,使用三个类加载器

  1. Bootstrap类加载器

  2. 扩展类加载器

  3. 系统类加载器

  4. Bootstrap类加载器加载核心java库。它是用本机代码编写的。引导类加载器负责将诸如java.lang.Object和其他运行时代码之类的关键java类加载到内存中。运行时类打包在jre / lib / rt.jar文件中。

    扩展类加载器加载扩展目录中的代码。它由ExtClassLoader类实现。

    系统类加载器在java.class.path上找到的代码,它映射到系统类路径变量。它由AppClassLoader类实现。默认情况下,所有用户类都由系统类加载器加载。

    Java ClassLoader是分层的,每当提出请求以加载类时,它都会将其委托给它的父级,这样就可以在运行时环境中维护唯一性。如果父类加载器没有找到该类,则类加载器本身会尝试加载该类。

    这意味着第一个System类加载器会将请求委托给Extensions类加载器,它将请求委托给Bootstrap类加载器,如果没有找到它将搜索类,然后Extensions类加载器将搜索类,如果没有找到则System如果没有找到类加载器将搜索类,则抛出ClassNotFoundException

    JVM总是以System类加载器开始加载类吗?

    如果我错了,请纠正我

1 个答案:

答案 0 :(得分:4)

术语“系统类加载器”用词不当。正如您所说的那样,它负责从类路径的位置加载类,这些类是应用程序类。

从Java 8开始,AppClassLoaderExtClassLoader都是java.net.URLClassLoader的子类,java.security.SecureClassLoader的子类是java.lang.ClassLoader的子类,Class.forName(String)的子类}}。所有这些类都由Bootstrap加载器加载,解决了鸡与蛋的问题。

每个运行时类都有一个定义类加载器。对于启动期间由Bootstrap加载程序定义的类,定义类加载器是Bootstrap加载程序。完成JVM初始化并尝试启动应用程序后,将查询Application类加载器(也称为System类加载器)以获取主类。 Application类加载器将遵循首先查询父类的标准委托模型,同样,Extension类加载器和任何类加载器将创建类将是类'定义类加载器。

现在,在解析由另一个类引用的类或调用myapp.foo.Bar时,包含该引用的类的定义加载器将用于解析该类。因此,当Application类加载器加载了您的类javax.swing.JButton并且它包含对javax.swing.JButton的引用时,将为该类查询其定义的类加载器(即Application类加载器),遵循委托模型最终得到Bootstrap加载器定义的javax.swing.JButton。因此javax.swing.JButton中的类引用只能通过Bootstrap加载器解析,这意味着myapp.foo.Bar不能包含对getClassLoader()类的引用,因为它不在范围内。

因此,JVM 明确查询时,比如解析主类时。

有第三方类加载器不严格遵循父委托模型,但无论它们委托的方式和加载方式如何,每个类(由URLClassLoader返回的一个)都会有一个定义加载器,将是用于解析类中引用的那个。 JVM确保一个类中相同的符号名称始终解析为相同的运行时类,而不管特定的类加载器如何实现查找。

请注意,在Java 9中,Extension类加载器已被Platform类加载器取代。此类加载器可能偏离简单父代理,即它可能委托给Application类加载器以加载应用程序提供的模块,该模块取代平台提供的模块。此外,内置类加载器不再是not的子类。