解释java.lang.NoSuchMethodError消息

时间:2010-05-31 20:34:00

标签: java 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”是什么意思?
为什么括号中有四种类型     (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));
}

2 个答案:

答案 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;

转换为:

intClassDocMemberDocStringboolean作为参数的方法,并返回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结果。