Интерпретация сообщения 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));
}
Ответы
Ответ 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
.