为什么jar包冲突会引发 java.lang.ClassNotFoundException错误

今天看了类加载机制,突然有了一个疑惑,根据类加载机制的双亲委派模型,要加载一个类会逐层向上委托加载,直到发起加载请求的类加载器,如果都没加载到就会报 java.lang.ClassNotFoundException错误。但是两个jar包有同名的类为什么会引起 java.lang.ClassNotFoundException这个报错呢

8个回答

两个不同版本的jar包,当ClassLoader要去加载一个类(loadClass)时,要先找到对应的Class的byte数组,Class一般是放在文件中的,当我们有两个jar包里面都包含我们要找的那个相同package的Class时,ClassLoader会找到那个Class呢,这个要看URLClassLoader
中的实现了,因为我们使用到的大部分ClassLoader都是继承URLClassLoader的,URLClassLoader最终将com.lzy.A格式转换成com/lzy/A.class这样的格式delegate给一个URLClassPath类去寻找对应的
文件,是按照字母顺序排序的,也就是a在b前面,1在2前面所以当有两个a-0.1.jar和a-0.2.jar时,首先find到的是a-0.1.jar中class文件,而这个class文件中并没有新版本中定义的方法,这方法解析时就会抛出NoSuchMethodError。

两个jar包有同名的类,虚拟机无法辨别到底是要哪一个

不能有同名的包,!!

同一项目下包名,类名都要唯一啊

逐层向上委托加载是在没有加载到的情况下,你一下加载到两个同名的,这是两回事。

感觉题主很可能是对Java的重载概念有些混淆。
首先重载是一个类与另一个同名类相比有着不同参数与不同返回值,但这两个类本质上是还是一个类,如果这两个类是子类的话必然继承同一个父类。
如果父类不同,且在同一个包内的子类是不可以重名的。
建议题主写jar包的时候最好别把同名类写到一个包里,利用spring的bean工厂标记扫描一下就可以

最好用maven管理jar包版本,这样就很少有这种错误了

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问