解释 java.lang.NoSuchMethodError 消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2945862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:48:04  来源:igfitidea点击:

Interpreting java.lang.NoSuchMethodError message

javanosuchmethoderror

提问by dougkramer

I get the following runtime error message (along with the first line of the stack trace, which points to line 94). I'm trying to figure out why it says no such method exists.

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

Line 94 of writeSummaryLink is shown below.

writeSummaryLink 的第 94 行如下所示。

QUESTIONS
What does "ILcom" or "Z" mean?
Why there are four types in parentheses (ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z) and one after the parentheses Ljava/lang/String; when the method printDocLinkForMenu clearly has five parameters?

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

CODE DETAIL
The writeSummaryLink method is:

代码
细节 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);
}

Here's the method line 94 is calling:

这是第 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));
}

回答by BalusC

What does "ILcom" or "Z" mean?

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

Those are mapping types for native types. You can find an overview 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

In addition, the signature "L fully-qualified-class ;"would mean the class uniquely specified by that name; e.g., the signature "Ljava/lang/String;"refers to the class java.lang.String. Also, prefixing [to the signature makes the array of that type; for example, [Imeans the int array type.

此外,签名"L fully-qualified-class ;"将意味着由该名称唯一指定的类;例如,签名"Ljava/lang/String;"是指类java.lang.String。此外,[签名的前缀使该类型的数组;例如,[I表示 int 数组类型。



As to your next question:

至于你的下一个问题:

Why there are four types in parentheses (ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z) and one after the parentheses Ljava/lang/String; when the method printDocLinkForMenu clearly has five parameters?

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

Because you're not running the code you think you're running. The actuallyrunning code is trying to call exactly that method described in the error message, with actually five parameters (the Ishould be counted separately) and a Stringreturn type, but this method doesn't exist in the runtime classpath (while it was available in the compiletime classpath), hence this error. Also see the NoSuchMethodErrorjavadoc:

因为您没有运行您认为正在运行的代码。在实际运行的代码试图调用正是方法在错误消息中所描述的,与实际的五个参数(的I应单独计算)和一个String返回类型,但这种方法不会在运行时类路径存在(而这是在现有编译时类路径),因此出现此错误。另请参阅NoSuchMethodErrorjavadoc

Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.

Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.

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

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

So, verify if you're actually running the right version of the code as you've posted in your question and are using the right dependencies in the runtime classpath and not having duplicate different versioned libraries in the classpath.

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

Update: the exception signifies that the actualcode is (implicitly) trying to use the method like as follows:

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

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

Because it is expecting a Stringoutcome while it is declared void.

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

回答by JRL

From section 4.3.2of the JVM Spec:

来自JVM 规范的第 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

From section 4.3.3, Method descriptors:

第 4.3.3 节,方法描述符

A method descriptor represents the parameters that the method takes and the value that it returns:

方法描述符表示该方法采用的参数及其返回的值:

MethodDescriptor:
        ( ParameterDescriptor* ) ReturnDescriptor

Thus,

因此,

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

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

translates to:

翻译成:

A method with int, ClassDoc, MemberDoc, Stringand booleanas parameters, and which returns a String. Note that only reference parameters are separated with a semicolon, since the semicolon is part of their character representation.

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



So, to sum up:

所以,总结一下:

Why there are four types in parentheses (ILcom/sun/javadoc/ClassDoc;Lcom/sun/javadoc/MemberDoc;Ljava/lang/String;Z) and one after the parentheses Ljava/lang/String; when the method printDocLinkForMenu clearly has five parameters?

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

There are five parameters (int, ClassDoc, MemberDoc, String, boolean) and one return type (String).

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