我收到以下运行时错误消息(以及堆栈跟踪的第一行,指向第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”是什么意思?
为什么括号中有四种类型
(ILcom /太阳/的Javadoc / ClassDoc; LCOM /太阳/的Javadoc / MemberDoc; Ljava /郎/字符串; Z)
一个在括号后面
Ljava /郎/字符串;
当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));
}
答案 0 :(得分:82)
来自JVM规范的section 4.3.2:
Character Type Interpretation ------------------------------------------ B byte signed byte C char Unicode character D double double-precision floating-point value F float single-precision floating-point value I int integer J long long integer L<classname>; reference an instance of class S short signed short Z boolean true or false [ reference one array dimension
来自section 4.3.3, Method descriptors:
方法描述符表示方法采用的参数及其返回的值:
MethodDescriptor:
( ParameterDescriptor* ) ReturnDescriptor
因此,
(ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z)
Ljava/lang/String;
转换为:
以int
,ClassDoc
,MemberDoc
,String
和boolean
作为参数的方法,并返回String
。请注意,只有参考参数用分号分隔,因为分号是其字符表示的一部分。
所以,总结一下:
为什么括号中有四种类型(ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z),括号后面有一个Ljava / lang / String;当printDocLinkForMenu方法显然有五个参数?
有五个参数(int,ClassDoc,MemberDoc,String,boolean)和一个返回类型(String)。
答案 1 :(得分:16)
“ILcom”或“Z”是什么意思?
这些是本机类型的映射类型。您可以找到概述here。
Native Type | Java Language Type | Description | Type signature ---------------+--------------------+------------------+---------------- unsigned char | jboolean | unsigned 8 bits | Z signed char | jbyte | signed 8 bits | B unsigned short | jchar | unsigned 16 bits | C short | jshort | signed 16 bits | S long | jint | signed 32 bits | I long long | jlong | signed 64 bits | J __int64 | | | float | jfloat | 32 bits | F double | jdouble | 64 bits | D
此外,签名
"L fully-qualified-class ;"
表示该名称唯一指定的类;例如,签名"Ljava/lang/String;"
指的是类java.lang.String
。此外,在签名前加[
会生成该类型的数组;例如,[I
表示int数组类型。
关于你的下一个问题:
为什么括号中有四种类型(ILcom / sun / javadoc / ClassDoc; Lcom / sun / javadoc / MemberDoc; Ljava / lang / String; Z),括号后面有一个Ljava / lang / String;当printDocLinkForMenu方法显然有五个参数时?
因为你没有运行你认为正在运行的代码。 实际正在运行的代码正在尝试完全调用错误消息中描述的方法,实际上有五个参数(I
应单独计算)和String
返回类型,但是这个方法在运行时类路径中不存在(虽然它在compiletime类路径中可用),因此出现此错误。另请参阅NoSuchMethodError
javadoc:
如果应用程序试图调用类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出该异能。
通常,编译器会捕获此错误;如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。
因此,请验证您是否实际运行了正确版本的代码,因为您已在问题中发布并且在运行时类路径中使用了正确的依赖项,并且在类路径中没有重复的不同版本库。
更新:该异常表示实际代码(隐式)尝试使用如下方法:
String s = printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false);
因为它在声明为String
时期望void
结果。