Java类加载需掌握触发时机、类加载器分工、双亲委派机制及静态块执行顺序:主动使用(new、静态字段/方法、Class.forName)、打印ClassLoader链、-XX:+TraceClassLoading追踪、重写findClass而非loadClass、父子类静态块按继承顺序且仅执行一次。

Java 类加载考点精析教程,不是靠“搜教程标题”就能高效掌握的。真正管用的方式,是抓住核心机制、典型场景和高频陷阱,结合 JVM 自身行为验证。查得准,比看得多更重要。
类加载触发时机怎么查?
看代码里有没有「主动使用」行为:
-
new MyClass() - 访问非 final 静态字段(如
MyClass.count,但MyClass.CONST不会触发) - 调用静态方法(
MyClass.doWork()) -
Class.forName("xxx")(默认初始化) - 初始化子类时,父类自动先加载并初始化
- 启动时 main 方法所在类
注意:ClassLoader.loadClass("xxx") 只加载不初始化;Class.forName(name, false, cl) 也能跳过初始化。
类加载器分工怎么查?
运行时直接打印类加载器链:
System.out.println(MyClass.class.getClassLoader()); // 应用类加载器 System.out.println(String.class.getClassLoader()); // null(Bootstrap 加载,C++ 实现) System.out.println(Objects.class.getClassLoader()); // null(Java 9+ 模块化后,部分核心类由 platform loader 管理)
再配合 -XX:+TraceClassLoading 启动参数,启动时加这个:
java -XX:+TraceClassLoading MyApp
控制台会逐行输出 [Loaded com.example.ServiceImpl from file:/app.jar],一眼看清每个类是谁加载、从哪来的。
立即学习“Java免费学习笔记(深入)”;
双亲委派怎么查是否被破坏?
重点查自定义类加载器是否重写了 loadClass() —— 正确做法是只重写 findClass(),让父委派逻辑保持完整;如果在 loadClass() 里直接 defineClass,就绕过了委派,可能引发 NoClassDefFoundError 或重复加载。
静态块执行顺序怎么查?
写个父子继承链 + 静态字段访问,例如:
class A { static { System.out.println("A"); } }
class B extends A { static { System.out.println("B"); } }
public class Test { public static void main(String[] args) { System.out.println(B.field); } }运行结果就是加载顺序的铁证:先 A 再 B,且只执行一次。
不复杂但容易忽略


















