ClassLoader 是JVM中的一个特殊组件,负责在类首次使用时加载类的字节码到内存中。它允许动态地从各种来源(文件系统、网络、归档等)加载类。
类加载器的类型:
jre/lib/ext 加载扩展。ClassLoader实现了委托机制:首先尝试从父加载器加载类(parent-first),只有在失败时才会自行查找。
类的隔离: 每个类加载器创建自己的“类可见性”区域。通过不同加载器加载的两个同名类被视为JVM中的不同类型。
创建自定义加载器的示例:
class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // 您的查找和加载类字节码的代码 return super.findClass(name); } }
两个同名类在不同加载器下是否可以被视为JVM中的一个类?
答案: 不可以!JVM认为类是唯一的,依据(完整类名,类加载器)。因此,相同的类在不同的加载器下会被视为不同的。
故事
在支持插件架构的企业应用程序中,插件使用不同的类加载器加载。结果,尝试在主应用程序和插件之间传递类型为接口(PluginInterface)的对象导致ClassCastException,因为同一接口被不同的加载器加载。
故事
在使用自定义类加载器时,未实现对父加载器的委托。这导致标准库类被重复加载,产生奇怪的ClassCastException和LinkageError错误。
故事
在大型Java EE服务器中,不同的应用程序加载同一库的不同版本。加载器链的配置不当导致类在应用程序之间冲突,导致大规模内存泄漏和由于版本冲突导致的故障。