为何Java中同一个类会被两个不同类加载器重复加载?
为什么两个URLClassLoader能重复加载同一个类?
核心原因很简单:你的应用类加载器(Application ClassLoader)根本找不到example.ToBeLoaded这个类,所以双亲委派机制没起到“只加载一次”的作用。
具体逻辑拆解:
- 双亲委派的核心规则是:子类加载器收到类加载请求时,优先把请求委托给父加载器处理;只有父加载器在自己管辖的类路径里找不到目标类,子类加载器才会自行加载。
- 你代码里的
tobeloaded-1.0-SNAPSHOT.jar放在桌面,这个路径不在应用类加载器的默认类路径(系统classpath)范围内。所以当cl1和cl2分别委托父加载器加载example.ToBeLoaded时,父加载器找不到该类,只能返回加载失败。 - 此时
cl1和cl2会各自去自己指定的jar路径中加载目标类,最终生成两个完全独立的Class对象——在JVM里,同一个类由不同类加载器加载产生的实例,会被视为完全不同的类,所以child2 == child1和child2.equals(child1)都会返回false。
验证结论的小实验:
如果把这个jar包放到应用类加载器的类路径里(比如添加到系统classpath,或是IDE项目的依赖目录中),再运行代码,你会发现child2 == child1返回true——因为此时应用类加载器能找到并加载该类,cl1和cl2都会直接复用父加载器已经加载好的类实例。
内容的提问来源于stack exchange,提问作者Machi
相关产品推荐
相关产品推荐

