标签:nosuchmethoderror java guava classpath
代码(编译):
for (Method m : ImmutableList.class.getMethods()) {
System.out.println(m);
}
ImmutableList.copyOf(Arrays.asList(new PlayerLevel[0]));
输出(注释和缩写):
public final void com.google.common.collect.ImmutableList.add(int,java.lang.Object)
----> public static com.google.common.collect.ImmutableList com.google.common.collect.ImmutableList.copyOf(java.lang.Iterable)
public static com.google.common.collect.ImmutableList com.google.common.collect.ImmutableList.copyOf(java.util.Iterator)
(lots of other methods)
java.lang.NoSuchMethodError: com.google.common.collect.ImmutableList.copyOf(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableList;
咦?
(如果日志不够清楚,我得到一个错误,说ImmutableList.copyOf(List)不是一个方法,但通过循环遍历所有方法,我看到有一个copyOf(Iterable),而List实现了Iterable.)
解决方法:
两种方法在编译时都兼容.但运行时是另一种野兽.我假设您的代码针对较旧版本的Google Collections进行编译,但针对较新版本运行.
编辑:
详细情况:
鉴于线条
List<String tmpArray = Arrays.asList(new PlayerLevel[0]);
ImmutableList.copyOf(tmpArray);
编译器开始在ImmutableList中寻找一个合适的方法,名称为copyOf,一个参数与静态类型List< String>兼容.编译器可见的类的版本只提供一个匹配:
ImmutableList.copyOf(Collection<T> arg0);
请注意,编译器对tmpArray的实际类型不感兴趣,只考虑静态类型(又称“正式类型”).
编译器将所选方法的签名写入类文件.
在运行时,类加载器/链接器读取类,找到方法的签名
ImmutableList.copyOf(Collection<T> arg0);
并在ImmutableList上执行查找(而不是搜索!)以获得确切的给定签名.兼容性在这里无关紧要,这是编译器的工作.如果你使用这样的反射,你会得到相同的结果:
ImmutableList.class.method("copyOf", Collection.class);
在这两种情况下,Java只使用完全给定的类型执行查找.它不执行类似“可以使用给定类型调用的返回方法”的搜索.
在您的情况下,运行时类路径和编译时类是不同的.因此类加载器/链接器无法执行查找.
退一步
此问题显示了不同级别的兼容性:
>二进制兼容性:扔进一个新罐子就是这样.
>源兼容性:您必须编译源代码,但不必更改它.
>行为兼容性或语义兼容性:必须更改客户端代码.
您可以使用这些关键字浏览此网站或Google以获取更多信息.二进制兼容性的一个很好的参考是Evolving Java-based APIs的三个部分.
标签:nosuchmethoderror,java,guava,classpath 来源: https://codeday.me/bug/20190826/1732718.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。