Java 尝试使用更高版本的JAR文件时出现NoSuchMethod错误

Java 尝试使用更高版本的JAR文件时出现NoSuchMethod错误,java,jar,versioning,Java,Jar,Versioning,在一个程序中,我使用两个外部jar库。 外部库X中有一个类调用库Y中类的方法m。库X是用库Y的1.0版编译的。然而,由于我在代码中使用libraryY用于其他目的,所以我更喜欢使用它的最新版本(比方说5.0)。 我的问题是,当我执行代码时,库X抱怨方法m不再存在(抛出NoSuchMethod错误)。然而,方法是存在的 问题可能与我使用的库Y比编译时出现的版本更新有关?(虽然向后兼容,但字节码不同?)。如果是这种情况,那么我会有点困惑,因为我认为java方法调用是以字节码表示为符号引用(例如,方法

在一个程序中,我使用两个外部jar库。 外部库
X
中有一个类调用库
Y
中类的方法
m
。库
X
是用库
Y
的1.0版编译的。然而,由于我在代码中使用library
Y
用于其他目的,所以我更喜欢使用它的最新版本(比方说5.0)。 我的问题是,当我执行代码时,库
X
抱怨方法
m
不再存在(抛出NoSuchMethod错误)。然而,方法是存在的

问题可能与我使用的库
Y
比编译时出现的版本更新有关?(虽然向后兼容,但字节码不同?)。如果是这种情况,那么我会有点困惑,因为我认为java方法调用是以字节码表示为符号引用(例如,方法签名),而不是直接引用(例如,偏移量),但我可能误解了一些东西

谢谢你的澄清

[…]我认为java方法调用以字节码表示为符号引用(例如,方法签名),而不是直接引用(例如,偏移量)[…]

你想得对;但是
Y
v5.0中的方法可能与
Y
v1.0中的方法具有不同的签名,即使它们具有相同的名称;例如,它现在可能有不同数量的参数,或者有不同类型的参数,或者可能变成了
静态
或非
静态

[…]我认为java方法调用以字节码表示为符号引用(例如,方法签名),而不是直接引用(例如,偏移量)[…]


你想得对;但是
Y
v5.0中的方法可能与
Y
v1.0中的方法具有不同的签名,即使它们具有相同的名称;例如,它现在可能有不同数量的参数,或者不同类型的参数,或者它可能变成了
静态的
或者非
静态的
调用的
X
方法名可能仍然存在于jar
Y
中,但是可能方法签名已经更改了——也就是说,参数的数量或类型可能已更改。

正在调用的
X
方法名称可能仍存在于jar
Y
中,但可能方法签名已更改,也就是说,参数的数量或类型可能已更改。

确实如此。签名的变化非常微妙。原始版本中的方法将“int”作为参数,而新版本中的方法是“long”。我没有意识到我只是在验证“兼容”方法是否仍然存在,而不是“精确”方法是否仍然存在。谢谢。@Sergio:不客气。是的,在没有显式JVM支持的情况下,很容易忽略编译器默默处理的事情——隐式加宽转换、协变返回等。签名的变化非常微妙。原始版本中的方法将“int”作为参数,而新版本中的方法是“long”。我没有意识到我只是在验证“兼容”方法是否仍然存在,而不是“精确”方法是否仍然存在。谢谢。@Sergio:不客气。是的,在没有显式JVM支持的情况下,很容易忽略编译器默默处理的事情——隐式加宽转换、协变返回等。