75

我收到以下运行时错误消息(以及堆栈跟踪的第一行,它指向第 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/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));
}
4

2 回答 2

97

从JVM Spec 的第 4.3.2 节:

字符类型解释
------------------------------------------
B 字节 有符号字节
C char Unicode 字符
D double 双精度浮点值
F float 单精度浮点值
我 int 整数
J long long 整数
L<类名>; 引用类的实例
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,Stringboolean作为参数的方法,它返回一个String. 请注意,只有引用参数用分号分隔,因为分号是其字符表示的一部分。


所以,总结一下:

为什么括号中有四种类型(ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z)和括号后面的一种是Ljava/lang/String;当 printDocLinkForMenu 方法明明有五个参数时?

有五个参数(int、ClassDoc、MemberDoc、String、boolean)和一种返回类型(String)。

于 2010-05-31T20:57:07.980 回答
18

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

这些是本机类型的映射类型。您可以在此处找到概述。

原生类型 | Java 语言类型 | 说明 | 类型签名
---------------+--------------------+------------- -----+----------------
无符号字符 | jboolean | 无符号 8 位 | Z
签名字符 | jbyte | 有符号的 8 位 | 乙
无符号短 | jchar | 无符号 16 位 | C
短 | 短片 | 带符号的 16 位 | 小号
长 | 金特 | 带符号的 32 位 | 我
长长| 金龙 | 有符号的 64 位 | Ĵ
__int64 | | |
浮动 | jfloat | 32 位 | F
双 | jdouble | 64 位 | 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 返回类型,但是这个方法在运行时类路径中不存在(虽然它在编译时类路径),因此出现此错误。另请参阅NoSuchMethodErrorjavadoc

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

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

因此,请验证您是否真的在运行您在问题中发布的正确版本的代码,并且在运行时类路径中使用正确的依赖项,并且在类路径中没有重复的不同版本库。

更新:异常表示实际代码(隐式)尝试使用如下方法:

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

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

于 2010-05-31T20:49:51.257 回答