J'obtiens le message d'erreur d'exécution suivant (avec la première ligne de la trace de pile, qui pointe vers la ligne 94). J'essaie de comprendre pourquoi il dit qu'aucune telle méthode n'existe.
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)
La ligne 94 de writeSummaryLink est illustrée ci-dessous.
QUESTIONS
Que signifie "ILcom" ou "Z"?
Pourquoi il y a quatre types entre parenthèses (ILcom/Sun/javadoc/ClassDoc; Lcom/Sun/javadoc/MemberDoc; Ljava/lang/String; Z) et un après les parenthèses Ljava/lang/String; lorsque la méthode printDocLinkForMenu a clairement cinq paramètres?
DÉTAIL DU CODE
La méthode writeSummaryLink est:
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);
}
Voici la méthode que la ligne 94 appelle:
public void printDocLinkForMenu(int context, ClassDoc classDoc, MemberDoc doc,
String label, boolean strong) {
String docLink = getDocLink(context, classDoc, doc, label, strong);
print(deleteParameterAnchors(docLink));
}
De section 4.3.2 de la spécification JVM:
Interprétation des types de caractères ------------------------------------- ----- B octet signé octet C char Caractère Unicode D double virgule flottante double précision F flottant virgule flottante simple précision valeur I entier entier J entier long long L <nomclasse>; référence à une instance de classe S court signé court Z booléen vrai ou faux [référence à une dimension de tableau
De section 4.3.3, Descripteurs de méthode :
Un descripteur de méthode représente les paramètres que la méthode prend et la valeur qu'elle renvoie:
MethodDescriptor:
( ParameterDescriptor* ) ReturnDescriptor
Ainsi,
(ILcom/Sun/javadoc/ClassDoc;Lcom/Sun/javadoc/MemberDoc;Ljava/lang/String;Z) Ljava/lang/String;
se traduit par:
Une méthode avec int
, ClassDoc
, MemberDoc
, String
et boolean
comme paramètres, et qui renvoie un String
. Notez que seuls les paramètres de référence sont séparés par un point-virgule, car le point-virgule fait partie de leur représentation de caractère.
Donc, pour résumer:
Pourquoi il existe quatre types entre parenthèses (ILcom/Sun/javadoc/ClassDoc; Lcom/Sun/javadoc/MemberDoc; Ljava/lang/String; Z) et un après les parenthèses Ljava/lang/String; lorsque la méthode printDocLinkForMenu a clairement cinq paramètres?
Il y a cinq paramètres (int, ClassDoc, MemberDoc, String, boolean) et un type de retour (String).
Que signifie "ILcom" ou "Z"?
Ce sont des types de mappage pour les types natifs. Vous pouvez trouver un aperçu ici .
Type natif | Java Type de langage | Description | Signature de type --------------- + ------------ -------- + ------------------ + ---------------- non signé char | jboolean | non signé 8 bits | Z signé char | jbyte | signé 8 bits | B non signé court | jchar | non signé 16 bits | C court | jshort | signé 16 bits | S long | jint | signé 32 bits | I long long | jlong | signé 64 bits | J __ int64 | | | float | jfloat | 32 bits | F Double | jdouble | 64 bits | D
De plus, la signature
"L fully-qualified-class ;"
signifierait la classe uniquement spécifiée par ce nom; par exemple, la signature"Ljava/lang/String;"
fait référence à la classeJava.lang.String
. De plus, le préfixe[
à la signature crée le tableau de ce type; par exemple,[I
signifie le type de tableau int.
Quant à votre prochaine question:
Pourquoi il y a quatre types entre parenthèses (ILcom/Sun/javadoc/ClassDoc; Lcom/Sun/javadoc/MemberDoc; Ljava/lang/String; Z) et un après les parenthèses Ljava/lang/String; quand la méthode printDocLinkForMenu a clairement cinq paramètres?
Parce que vous n'exécutez pas le code que vous pensez exécuter. Le code en cours d'exécution en fait essaie d'appeler exactement la méthode décrite dans le message d'erreur, avec en fait cinq paramètres (le I
doit être compté séparément) et un String
return type, mais cette méthode n'existe pas dans le chemin de classe d'exécution (alors qu'elle était disponible dans le chemin de classe compiletime), d'où cette erreur. Voir aussi NoSuchMethodError
javadoc :
Lancé si une application tente d'appeler une méthode spécifiée d'une classe (statique ou instance) et que cette classe n'a plus de définition de cette méthode.
Normalement, cette erreur est détectée par le compilateur; cette erreur ne peut se produire au moment de l'exécution que si la définition d'une classe a changé de manière incompatibl.
Donc, vérifiez si vous exécutez réellement la bonne version du code comme vous l'avez publié dans votre question et utilisez les bonnes dépendances dans le chemin de classe d'exécution et que vous n'avez pas de bibliothèques de versions différentes en double dans le chemin de classe.
Mise à jour : l'exception signifie que le code réel essaie (implicitement) d'utiliser la méthode comme suit:
String s = printDocLinkForMenu(context, cd, (MemberDoc) emd, name, false);
Parce qu'il attend un résultat String
alors qu'il est déclaré void
.