截至Java 8,我知道类加载器的层次结构如下:
引导类加载器 → 扩展类加载器 → 应用程序类加载器
Java 9中类加载器层次结构有什么变化,它是如何工作的?
截至Java 8,我知道类加载器的层次结构如下:
引导类加载器 → 扩展类加载器 → 应用程序类加载器
Java 9中类加载器层次结构有什么变化,它是如何工作的?
这是Java 9的迁移指南,其中提到了以下与模块系统有关的类加载器实现变化:
新的类加载器实现
JDK 9继承自1.2版本以来存在的类加载器层次结构,但对于实现模块系统做出了以下更改:
应用程序类加载器不再是URLClassLoader的实例,而是一个内部类。它是非Java SE和JDK模块中类的默认加载器。
扩展类加载器已被重命名,现在是平台类加载器。 Java SE平台中的所有类都可以通过平台类加载器访问。此外,Java社区进程标准化但不属于Java SE平台的模块中的类也可以通过平台类加载器进行访问。
虽然某些类可通过平台类加载器访问,但这并不意味着类确实是由平台类加载器定义的。 Java SE平台中的某些类由平台类加载器定义,而其他类则由引导类加载器定义。应用程序不应依赖于哪个类加载器定义了哪个平台类。
JDK 9中的更改可能会影响使用null(即引导类加载器)作为父类加载器创建类加载器并假定所有平台类都可见于父类的代码。这种代码可能需要更改以将平台类加载器用作父级(请参阅ClassLoader.getPlatformClassLoader)。
平台类加载器不是URLClassLoader的实例,而是一个内部类。
引导类加载器仍然内置于Java虚拟机中,并且在ClassLoader API中由null表示。它定义了一些关键模块中的类,例如java.base。因此,它定义的类比JDK 8中少得多,因此使用-Xbootclasspath/a部署或将null作为父级创建类加载器的应用程序可能需要根据前面所述进行更改。
Java-9中修订的ClassLoader
规定如下:
Java运行时拥有以下内置类加载器:
Bootstrap class loader
: 虚拟机内置的类加载器,通常表示为null,并且没有父级。
Platform class loader
: 允许升级/覆盖定义到平台类加载器的模块,并且当升级的模块读取定义到除平台类加载器及其祖先之外的类加载器的模块时,那么平台类加载器可能需要委派给其他的类加载器,例如应用程序类加载器。换句话说,定义到除平台类加载器及其祖先之外的类加载器的命名模块的类可能对平台类加载器可见。
System class loader
: 也被称为应用程序类加载器,与平台类加载器不同。系统类加载器通常用于在应用程序类路径、模块路径和JDK特定工具上定义类。平台类加载器是系统类加载器的父级或祖先,所有平台类都对它可见。
PlatformClassLoader
加载哪些类? - Sergey Zolotarev
PlatformClassLoader
加载哪些类? - Sergey Zolotarev