验证类隔离需检查四点:1. 不同加载器加载的同名类class对象不相等;2. 跨加载器实例强制转换抛classcastexception;3. 自定义加载器parent为null且委托机制正常;4. 同名类静态变量互不共享。

验证自定义类加载器是否实现类隔离,核心是检查两个关键点:同一类名在不同类加载器下是否生成不同的 Class 对象;以及它们的实例是否无法互相赋值或调用对方加载的类方法(因运行时类型不兼容)。
1. 检查 Class 对象是否不相等(同一类名,不同 ClassLoader)
这是最直接的隔离证据。即使类字节码完全相同,只要由不同类加载器加载,JVM 就视为不同类型:
- 用你的自定义类加载器 A 加载
com.example.MyService - 用另一个自定义类加载器 B(或系统类加载器)也加载
com.example.MyService - 比较两者返回的
Class实例:classA != classB→ 隔离成立 - 注意:不能用
classA.equals(classB),要直接用!=或== false
2. 尝试跨加载器类型转换(ClassCastException 测试)
创建一个由类加载器 A 加载的实例,尝试强制转为由类加载器 B 加载的同名类类型:
Object objA = loaderA.loadClass("com.example.MyService").getDeclaredConstructor().newInstance();-
MyServiceB serviceB = (MyServiceB) objA;(其中MyServiceB是 loaderB 加载的类的引用类型) - 若抛出
ClassCastException(提示 “cannot cast … to …”),说明类型不可见、不兼容 → 隔离生效 - 若编译都不通过(如找不到
MyServiceB类型),说明编译期已隔离(更彻底)
3. 检查类加载器委托链与 parent 关系
隔离失效常见于错误配置了 parent。验证方式:
- 打印你自定义加载器的
getParent(),确认不是意外指向了应用类加载器(AppClassLoader)或扩展类加载器 - 若希望强隔离,应显式传入
null或一个独立的、无共享 parent 的加载器(如new URLClassLoader(urls, null)) - 调用
loaderA.loadClass("java.lang.String")应始终返回系统加载的String(双亲委派保证),但loaderA.loadClass("com.example.MyService")必须不走 parent → 可覆写loadClass(String, boolean)并加日志验证委托行为
4. 验证静态变量/单例是否不共享
在待测类中添加一个 public static int counter = 0; 和 public static void inc() { counter++; }:
- 用 loaderA 加载并调用
inc()三次 →counter == 3 - 用 loaderB 加载同一个类,读取其
counter→ 应为0(不是 3) - 再对 loaderB 的实例调用
inc()→ 其counter独立变化 - 这证明静态上下文随类加载器隔离,而非全局共享
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











