Подтвердить что ты не робот

Интерпретация сообщения 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)

Строка 94 writeSummaryLink показана ниже.

ВОПРОСЫ
Что означает "ILcom" или "Z"?
Почему в круглых скобках четыре типа   (ILcom/ВС/Javadoc/ClassDoc; Lcom/ВС/Javadoc/MemberDoc; Ljava/языки/String; Z) и один после круглых скобок   Ljava/языки/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));
}
4b9b3361

Ответ 1

Из раздел 4.3.2 спецификации JVM:

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

От раздел 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 в качестве параметров и возвращает a String. Обратите внимание, что только опорные параметры разделяются точкой с запятой, так как точка с запятой является частью их символьного представления.


Итак, подведем итог:

Почему в круглых скобках есть четыре типа (ILcom/sun/javadoc/ClassDoc; Lcom/sun/javadoc/MemberDoc; Ljava/lang/String; Z) и один после круглых скобок Ljava/lang/String; когда метод printDocLinkForMenu явно имеет пять параметров?

Существует пять параметров (int, ClassDoc, MemberDoc, String, boolean) и один возвращаемый тип (String).

Ответ 2

Что означает "ILcom" или "Z"?

Это типы отображения для собственных типов. Вы можете найти обзор здесь.

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, но этот метод не существует в пути пути выполнения (пока он был доступен в классе classpath), следовательно, эта ошибка. Также см. NoSuchMethodError javadoc:

Брошено, если приложение пытается вызвать указанный метод класса (либо статический, либо экземпляр), и этот класс больше не имеет определения этого метода.

Обычно эта ошибка улавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение класса несовместимо изменилось.

Итак, проверьте, действительно ли вы используете правильную версию кода, как вы разместили в своем вопросе, и используете правильные зависимости в пути пути выполнения и не дублируете разные версии библиотек в пути к классам.

Обновить: исключение означает, что фактический код (неявно) пытается использовать метод следующим образом:

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

Потому что он ожидает результата String, пока он объявлен void.