JDK 9 的 PlatformClassLoader 只是简单改个名吗? 都知道JDK9之后将扩展类加载器ExtensionClassLoader重命名为平台类加载器PlatformClassLoader难道只是简单的重命名吗都有什么变化带来的变化1.双亲委派模型的改变JDK8双亲委派是严格的“向上查找”自定义——App——Ext——BootJDK9为了适配模块化当类加载器收到加载请求时会先判断该类是否属于某个具体的模块如果该类已经归属于某个模块Java 会直接将请求委派给负责该模块的类加载器而不再一层层往上托举什么谁判断的该类是否属于某个具体的模块is引入的BuiltinClassLoader判断的package jdk.internal.loader; protected Class? loadClassOrNull(String cn, boolean resolve) { synchronized (getClassLoadingLock(cn)) { // 检查这个类是否已经被加载过 Class? c findLoadedClass(cn); if (c null) { // 查找它属于哪个模块 LoadedModule loadedModule findLoadedModule(cn); // --------- 情况 A属于某个模块走直达 ----------- //查到了属于某个模块 if (loadedModule ! null) { //获取这个模块的类加载器 BuiltinClassLoader loader loadedModule.loader(); //如果是我自己 if (loader this) { //模块系统初始化完成后由我自己去加载 if (VM.isModuleSystemInited()) { c findClassInModuleOrNull(loadedModule, cn); } } else { //甩给对应的加载器实现“直达” c loader.loadClassOrNull(cn); } } else { //--------- 情况 B不属于任何已知模块走传统双亲委派) ----------- //向上委派 if (parent ! null) { c parent.loadClassOrNull(cn); } // 向下退回 if (c null hasClassPath() VM.isModuleSystemInited()) { c findClassOnClassPathOrNull(cn); } } } if (resolve c ! null) resolveClass(c); return c; } }什么是模块化JDK9之前只有包和Jar包问题一只要一个jar包在ClassPath里它里面所有的public类都能被任意访问但我的public只想当前组件内部用不暴露给外部问题二如果运行时两个jar包里有同名同包的类先扫描的会覆盖后面的会报错如NoSuchMethodError。模块化系统在包之上加了层模块一个模块不仅包含代码还包含核心描述文件module-info.java我导出了什么exports 只有被导出的包别的模块才能访问。我依赖了什么requires 明确声明我需要哪些模块才能运行。2.启动类加载器的改变脱离了 C 的“隐形”实现在过去Bootstrap ClassLoader 完全由 C 实现在 JDK 9 之后引入了BuiltinClassLoader的 Java 类。现在Bootstrap、Platform 和 App 加载器全都继承自BuiltinClassLoader。不再加载所有核心库过去所有的 Java 核心类都由 Bootstrap 一把抓。现在核心类被拆分成了不同的模块Bootstrap 只负责加载最核心的模块如java.base而java.sql数据库相关、java.xml等模块则交给了平台类加载器去加载。3.目录结构与打包文件消失rt.jar和tools.jar消失了所有内置类被重新打包成模块存在了lib/modules4.类加载器微调内置的三个加载器都改为了BuiltinClassLoader的子类好处运行时性能与启动速度的飞跃省去了沿途无效的逐级托举和全盘文件扫描强封装性阻止访问核心库内部的私有实现配置更可靠项目依赖A.jar A.jar依赖B.jar运行时不报错但是执行A.jar里的某行代码要加载B.jar里的类时就会抛ClassNotFoundException或NoClassDefFoundError现在模块化要求在module-info.java中明确声明requires哪些模块。package java.lang.module; public Builder requires(Requires req) { if (automatic) throw new IllegalStateException(Automatic modules cannot declare dependences); String mn req.name(); if (name.equals(mn)) throw new IllegalArgumentException(Dependence on self); if (requires.containsKey(mn)) throw new IllegalStateException(Dependence upon mn already declared); requires.put(mn, req); return this; }jlink自动裁剪用什么裁什么