我正在针对图书馆进行编程。
在版本1中,该库有一个方法getFoo(),它返回一个Map
在版本2中,该方法getFoo()现在返回一个Set
我认为我的代码很开心:
Object foo = library.getFoo();
并确定库是否返回Map或Set。
但是,当我针对库的版本1编译我的代码,但是针对版本2运行它时,我得到java.lang.NoSuchMethodError:getFoo()Ljava / util / Map;
至少这是
所发生的事情java version "1.7.0_21"
OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-0ubuntu0.12.04.1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
我现在通过使用反射来解决这个问题,但我认为没有必要。
所以我的问题是,执行Object foo = library.getFoo()是否安全,如果答案是“有时”或“它取决于”,那么为什么在这种情况下它没有问题呢?
答案 0 :(得分:1)
使用版本1编译代码时,类字节代码具有此方法的条目,返回类型为Map。在运行时加载类,类定义的getFoo()返回类型为Map,因此JVM无法定位该方法,因为您针对具有不同返回类型的方法的类的不同版本运行它(Set在你的情况下)。
答案 1 :(得分:0)
您获得的错误完全有效。
选项1:在代码中使用反射,使用您在运行时找到的任何版本的库动态地执行正确的操作。
选项2:如果您希望代码与任一版本的库一起运行,则需要在编译时提供这两个版本。您将需要一些代码来确定在运行时使用的版本,并有条件地执行编译为调用适当版本库的代码。如果图书馆作者不友好,您可能最终不得不解决类名冲突。
反思(选项1)可能是最简单,最灵活的方法。
您可能想要创建一个包装器API来抽象两个版本的库之间的差异,因此这种ickiness不会泄漏到您的应用程序的其余部分。