解释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;
转化为:
以int
, ClassDoc
, MemberDoc
, String
和boolean
为参数的方法,它返回一个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
结果。