解释java.lang.NoSuchMethodError消息

我得到以下运行时错误消息(以及第一行堆栈跟踪,指向94行)。 我想弄明白为什么说没有这样的方法存在。

java.lang.NoSuchMethodError: com.sun.tools.doclets.formats.html.SubWriterHolderWriter.printDocLinkForMenu( ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc; Ljava/lang/String;Z)Ljava/lang/String; at com.sun.tools.doclets.formats.html.AbstractExecutableMemberWriter.writeSummaryLink( AbstractExecutableMemberWriter.java:94) 

writeSummaryLink的第94行如下所示。

质询
“ILcom”或“Z”是什么意思?
为什么在括号中有四种types(ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z)和括号中的一个Ljava / lang / String; 当printDocLinkForMenu的方法显然有五个参数?

代码细节
writeSummaryLink方法是:

 protected void writeSummaryLink(int context, ClassDoc cd, ProgramElementDoc member) { ExecutableMemberDoc emd = (ExecutableMemberDoc)member; String name = emd.name(); writer.strong(); writer.printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false); // 94 writer.strongEnd(); writer.displayLength = name.length(); writeParameters(emd, false); } 

这里是方法94正在调用:

 public void printDocLinkForMenu(int context, ClassDoc classDoc, MemberDoc doc, String label, boolean strong) { String docLink = getDocLink(context, classDoc, doc, label, strong); print(deleteParameterAnchors(docLink)); } 

从JVM规范的第4.3.2节 :

字符types解释
 ------------------------------------------
 B字节有符号字节
 C char Unicode字符
 D双精度浮点值
 F浮点单精度浮点值
我整型
 J长整型
 →<类名>; 引用一个类的实例 
 S短签字
 Z布尔值true或false
 [引用一个数组维度

从4.3.3节,方法描述符 :

方法描述符表示方法需要的参数和它返回的值:

 MethodDescriptor: ( ParameterDescriptor* ) ReturnDescriptor 

从而,

(ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z) Ljava/lang/String;

转化为:

intClassDocMemberDocStringboolean为参数的方法,它返回一个String 。 请注意,只有引用参数用分号分隔,因为分号是其字符表示的一部分。


所以,总结一下:

为什么在括号中有四种types(ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z)和括号中的一个Ljava / lang / String; 当printDocLinkForMenu的方法显然有五个参数?

有五个参数(int,ClassDoc,MemberDoc,String,boolean)和一个返回types(String)。

“ILcom”或“Z”是什么意思?

这些是本地types的映射types。 你可以在这里find一个概述。

原生types|  Java语言types| 说明| types签名
 --------------- + -------------------- + ------------- ----- + ----------------
无符号字符|  jboolean | 无符号8位|  ž
 signed char |  jbyte | 签名8位| 乙
 unsigned short |  jchar | 无符号16位|  C
短|  jshort | 签名16位| 小号
长|  jint | 签名32位| 一世
很久很久  jlong​​ | 签名64位|  Ĵ
 __int64 |  |  |
 float |  jfloat |  32位|  F
双|  jdouble |  64位|  d

另外,签名"L fully-qualified-class ;" 意思是这个名字唯一指定的类; 例如签名"Ljava/lang/String;" 指的是java.lang.String类。 另外,在签名前加上这个types的数组。 例如, [I意思是int数组types。


至于你的下一个问题:

为什么在括号中有四种types(ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z)和括号中的一个Ljava / lang / String; 当printDocLinkForMenu的方法显然有五个参数?

因为你没有运行你认为正在运行的代码。 实际运行的代码正试图调用错误消息中描述的方法,实际上有五个参数( I应该单独计数)和一个String返回types,但是这个方法在运行时类path中不存在(虽然它是在编译时类path中可用),所以这个错误。 另请参阅NoSuchMethodError javadoc :

如果应用程序尝试调用某个类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出该方法。

通常,这个错误被编译器捕获; 这个错误只能在运行时发生,如果一个类的定义不兼容改变。

因此,请确认您是否实际运行了正确的代码版本,并且在运行时类path中使用正确的依赖关系,而不是在类path中重复使用不同版本的库。

更新 :exception表示实际代码是(隐式)尝试使用如下所示的方法:

 String s = printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false); 

因为它在声明为void时期待String结果。