Que signifient les erreurs « symbole introuvable » ou « impossible de résoudre le symbole » ?
P粉106711425
P粉106711425 2023-10-09 13:52:29
0
2
1271

Veuillez expliquer ce qui suit concernant les erreurs « symbole introuvable », « impossible de résoudre le symbole » ou « symbole introuvable » (en Java) :

  • Que signifient-ils ?
  • Quels facteurs peuvent causer ces problèmes ?
  • Comment les programmeurs résolvent-ils ces problèmes ?

Cette question vise à fournir une série de questions-réponses complètes sur ces erreurs de compilation courantes en Java.

P粉106711425
P粉106711425

répondre à tous(2)
P粉203792468

Si vous oubliez new, vous obtiendrez également cette erreur :

String s = String();

Comparaison

String s = new String();

Parce qu'un appel sans le mot-clé new 关键字的调用将尝试查找不带参数的名为 String tentera de trouver une méthode (native) nommée String qui ne prend aucun paramètre - et cette signature de méthode peut être indéfinie. p>

P粉946437474

0. Y a-t-il une différence entre ces erreurs ?

Ce n'est pas vrai. « Symbole introuvable », « Impossible de résoudre le symbole » et « Symbole introuvable » signifient tous la même chose. (Différents compilateurs Java sont écrits par différentes personnes, et différentes personnes utilisent des termes différents pour dire la même chose.)

1. Que signifie l'erreur « symbole introuvable » ?

Tout d'abord, il s'agit d'une erreur de compilation1. Cela signifie il y a un problème dans votre code source Java, ou il y a un problème avec la façon dont vous l'avez compilé.

Votre code source Java contient les éléments suivants :

  • Mots clés : Par exemple classwhile etc.
  • Texte : Tel que truefalse42'X'“嗨妈妈!”.
  • opérateur et autres jetons non alphanumériques : par exemple +={ etc.
  • Identifiant : Par exemple ReaderitoStringprocessEquibalancedElephants etc.
  • Commentaires et espaces.

Les erreurs « Symbole introuvable » sont liées aux identifiants. Lors de la compilation du code, le compilateur doit comprendre la signification de chaque identifiant dans le code.

L'erreur "Symbole introuvable" signifie que le compilateur ne peut pas effectuer cette opération. Votre code semble faire référence à quelque chose que le compilateur ne comprend pas.

2. Qu'est-ce qui cause l'erreur « symbole introuvable » ?

Pour la première commande, il n'y a qu'une seule raison. Le compilateur a cherché partout où l'identifiant devait être défini, mais n'a pas trouvé de définition. Cela peut être dû à diverses raisons. Les plus courants sont les suivants :

  • Pour les identifiants généraux :

    • Peut-être que votre nom est mal orthographié ; c'est StringBiulder 而不是 StringBuilder. Java ne peut pas et ne tente pas de compenser les fautes d'orthographe ou les erreurs typographiques.
    • Peut-être que vous vous êtes trompé ; c'est stringBuilder 而不是 StringBuilder. Tous les identifiants Java sont sensibles à la casse.
    • Peut-être que vous utilisez les traits de soulignement de manière incorrecte ; c'est-à-dire que mystringmy_string est différent. (Si vous vous en tenez aux règles de style Java, vous éviterez largement cette erreur...)
    • Peut-être essayez-vous d'utiliser quelque chose déclaré "ailleurs" ; c'est-à-dire dans un contexte différent de celui que vous avez implicitement demandé au compilateur de regarder. (Différentes classes ? Différentes portées ? Différents packages ? Différentes bases de code ?)
  • Pour les identifiants devant référencer des variables :

    • Peut-être avez-vous oublié de déclarer la variable.
    • Peut-être que la déclaration de variable est devenue hors de portée lorsque vous avez essayé de l'utiliser. (voir exemple ci-dessous)
  • Pour les identifiants qui doivent être des noms de méthode ou de champ :

    • Peut-être essayez-vous de référencer une méthode ou un champ hérité qui n'est pas déclaré dans la classe ou l'interface parent/ancêtre.

    • Peut-être essayez-vous de référencer une méthode ou un champ qui n'existe pas (c'est-à-dire qui n'a pas été déclaré) dans le type que vous utilisez, par exemple "rope".push()2 ;

    • Peut-être essayez-vous d'utiliser une méthode comme champ ou vice versa par exemple "rope".lengthsomeArray.length() ;

    • Peut-être avez-vous manipulé par erreur le tableau au lieu des éléments du tableau par exemple

       ;
      String strings[] = ...
          if (strings.charAt(3)) { ... }
          // maybe that should be 'strings[0].charAt(3)'
  • Pour les identifiants qui doivent être des noms de classe :

    • Peut-être avez-vous oublié d'importer la classe.

    • Peut-être avez-vous utilisé l'importation "astérisque" mais la classe n'est définie dans aucun package que vous avez importé.

    • Peut-être en avez-vous oublié un new comme ceci :

      String s = String();  // should be 'new String()'
    • Peut-être essayez-vous d'importer ou d'utiliser une classe qui est déjà déclarée dans le package par défaut ; c'est-à-dire là où se trouve la classe sans l'instruction package ;

      Conseil : Déballez. Vous ne devez utiliser le package par défaut que pour les applications simples composées d'une classe... ou d'au moins un fichier source Java.

  • Pour les cas où un type ou une instance ne semble pas avoir un membre (comme une méthode ou un champ) que vous attendez :

    • Peut-être avez-vous déclaré une classe imbriquée ou un paramètre générique, masquantle type que vous souhaitez utiliser.
    • Peut-être que vous cachez des variables statiques ou des variables d'instance.
    • Peut-être avez-vous importé le mauvais type ; par exemple, parce que la complétion ou la correction automatique de l'IDE pourrait le suggérer java.awt.List 而不是 java.util.List.
    • Peut-être utilisez-vous (compilez-vous) la mauvaise version de l'API.
    • Peut-être avez-vous oublié de convertir l'objet dans la sous-classe appropriée.
    • Peut-être avez-vous déclaré le type de la variable comme supertype du membre que vous recherchez.

Les questions sont généralement une combinaison de ce qui précède. Par exemple, peut-être que vous importez une classe dans java.io.*,然后尝试使用 Files 类...它位于 java.nio代码>而不是java.io。或者,也许您打算编写 File ...,它是 java.io .


L'exemple suivant illustre comment une portée de variable incorrecte peut conduire à une erreur « symbole introuvable » :

List strings = ...

for (int i = 0; i 

Cela donnera une erreur "symbole introuvable" pour i dans l'instruction if. Bien que nous ayons déclaré i plus tôt, cette déclaration n'est que l'instruction for et son corps if 语句中为 i 提供“找不到符号”错误。尽管我们之前声明了 i,但该声明仅for 语句及其主体范围if 语句中对 i 的引用看不到 iscope. La référence à i dans l'instruction if ne peut pas voir

la déclaration de i. C'est

hors de portéeif 语句移至循环内部,或在循环开始之前声明 i.


(La correction appropriée ici pourrait être de

.)

println 调用中给您一个编译错误,指出无法找到 iVoici un exemple déroutant où une faute de frappe provoque une erreur apparemment inexplicable « symbole introuvable » :

for (int i = 0; i 
🎜Ce sera en 🎜. Mais (je vous entends dire) je l’ai annoncé ! 🎜

Le problème c'est { 之前的分号 ( ; )。 Java 语言语法将该上下文中的分号定义为空语句。然后,空语句将成为 for le corps de la boucle. Ce code signifie donc en réalité :

for (int i = 0; i 

{ ... } 块不是 for 循环的主体,因此之前在 i 中的声明code>for La déclaration sort du cadre du bloc.


Ceci est un autre exemple d'erreur "symbole introuvable" provoquée par une faute de frappe.

int tmp = ...
int res = tmp(a + b);

Malgré la déclaration précédente, tmp(...) 表达式中的 tmp 是错误的。编译器将查找名为 tmp 的方法,但找不到。之前声明的 tmp est dans l'espace de noms de la variable, pas dans l'espace de noms de la méthode.

Dans les exemples que j'ai rencontrés, le programmeur a en fait omis un opérateur. Ce qu'il voulait à l'origine écrire était ceci :

int res = tmp * (a + b);

Il existe une autre raison pour laquelle le compilateur peut ne pas trouver de symbole lors de la compilation à partir de la ligne de commande. Vous avez peut-être simplement oublié de compiler ou de recompiler d'autres classes. Par exemple, si vous avez cours FooBar,其中 Foo 使用 Bar。如果您从未编译过 Bar 并且运行 javac Foo.java,您很容易发现编译器找不到符号 Bar 。简单的答案是将 FooBar 一起编译;例如javac Foo.java Bar.javajavac *.java. Ou mieux encore, utilisez des outils de construction Java tels que Ant, Maven, Gradle, etc.

Il existe d'autres raisons, plus obscures... dont je parlerai ci-dessous.

3. Comment corriger ces erreurs ?

De manière générale, vous devez d'abord découvrir quelle est la cause de l'erreur de compilation.

  • Regardez la ligne du fichier indiquée par le message d'erreur de compilation.
  • Déterminez de quel symbole parle le message d'erreur.
  • Découvrez pourquoi le compilateur dit que le symbole est introuvable, voir ci-dessus ;

Ensuite, vous réfléchissez à ce que votre code devrait dire. Enfin, vous déterminez quelles corrections doivent être apportées au code source pour accomplir ce que vous souhaitez.

Veuillez noter que toutes les « corrections » ne sont pas correctes. Considérez ceci :

for (int i = 1; i 

Supposons que le compilateur affiche « symbole introuvable » pour j. Il existe de nombreuses façons de "réparer" ce problème :

  • Je pourrais mettre l'interne for 更改为 for (int j = 1; j - probablement vrai.
  • Je pourrais ajouter une instruction for for 循环或外部 for 循环之前添加一个 for j
  • avant la boucle interne for ou la boucle externe for
  • - pourrait être correcte. for 循环中将 j 更改为 i
  • Je pourrais changer
  • en i à l'intérieur de la boucle interne for - probablement faux !
Attendez.

Le fait est que vous

devez 🎜 comprendre ce que votre code essaie de faire afin de trouver la bonne solution. 🎜

4. Raison inconnue

Dans les quelques cas suivants, "symbole introuvable" semble déroutant... jusqu'à ce qu'on y regarde de plus près.

  1. Dépendances incorrectes : Si vous utilisez un IDE ou un outil de construction qui gère votre chemin de construction et les dépendances du projet, vous avez peut-être commis une erreur avec les dépendances, par exemple en omettant une dépendance ou en sélectionnant la mauvaise version. Si vous utilisez un outil de build (Ant, Maven, Gradle, etc.), vérifiez les fichiers de build de votre projet. Si vous utilisez un IDE, vérifiez la configuration du chemin de build de votre projet.

  2. Symbole 'var' introuvable : vous essayez peut-être d'utiliser une ancienne version pour compiler en utilisant l'inférence de type de variable locale (c'est-à-dire que var 声明)的源代码编译器或更旧的 --source 级别。 var a été introduit dans Java 10. Vérifiez votre version du JDK et créez également des fichiers (si cela se produit dans IDE) Paramètres IDE

    .
  3. Vous n'avez pas compilé/recompilé : Parfois, les nouveaux programmeurs Java ne comprennent pas comment fonctionne la chaîne d'outils Java, ou n'implémentent pas de « processus de construction » répétable, par exemple en utilisant des IDE, Ant, Maven, Gradle, etc. . Dans ce cas, le programmeur peut finir par rechercher une erreur fantôme qui a en réalité été provoquée, par exemple, par une recompilation incorrecte du code.

    Un autre exemple est lorsque vous utilisez (Java 9+) java SomeClass.java 编译和运行类时。如果该类依赖于您尚未编译(或重新编译)的另一个类,则您可能会收到涉及第二类的“无法解析符号”错误。其他源文件不会自动编译。 java Le nouveau mode "Compiler et exécuter" de la commande n'est pas adapté à l'exécution de programmes avec plusieurs fichiers de code source.

  4. Problème de construction précoce : les premières versions peuvent échouer, entraînant l'absence de classes dans le fichier JAR. Si vous utilisez des outils de build, vous remarquerez généralement de tels échecs. Cependant, si vous obtenez des fichiers JAR auprès de quelqu'un d'autre, vous comptez sur eux pour les construire correctement et remarquer les erreurs. Si vous soupçonnez cela, utilisez tar -tvf pour répertorier le contenu du fichier JAR suspect.

  5. Problèmes d'IDE : Des personnes ont signalé des situations dans lesquelles leur IDE était confus et le compilateur de l'IDE ne pouvait pas trouver une classe qui existe... ou vice versa.

    • Cela peut arriver si l'EDI est configuré avec la mauvaise version du JDK.

    • Cela peut se produire si le cache de l'EDI n'est pas synchronisé avec le système de fichiers. Il existe des moyens spécifiques à l'EDI pour résoudre ce problème.

    • Cela peut être un bug de l'IDE. Par exemple, @Joel Costigliola décrit un scénario dans lequel Eclipse ne parvient pas à gérer correctement l'arborescence "test" Maven : Voir cette réponse . (Apparemment, ce bug particulier a été corrigé il y a longtemps.)

  6. Problème Android : Lorsque vous programmez pour Android, si vous tombez sur un fichier de classe lié à R 相关的“找不到符号”错误,请注意 R 符号由 context.xml 文件定义。检查您的 context.xml 文件是否正确且位于正确的位置,以及是否已生成/编译相应的 R. Notez que les symboles Java sont sensibles à la casse, donc les identifiants XML correspondants sont également sensibles à la casse.

    D'autres erreurs de symboles sur Android peuvent être dues aux raisons mentionnées précédemment ; telles que des dépendances manquantes ou incorrectes, des noms de packages incorrects, des méthodes ou des champs qui n'existent pas dans une version spécifique de l'API, des erreurs d'orthographe/de frappe, etc.

  7. Masquer les classes système : j'ai vu des cas où le compilateur se plaignait que substring était un symbole inconnu, comme celui-ci

    String s = ...
    String s1 = s.substring(1);

    Il s'avère que le programmeur a créé sa propre version de String et que sa version de la classe n'a pas défini la méthode String 版本,并且他的类版本没有定义 substring 方法。我见过人们使用 SystemScanner. J'ai vu des gens utiliser System, Scanner et d'autres classes pour ce faire.

    Leçon : Ne définissez pas votre propre classe avec le même nom qu'une classe de bibliothèque publique !

    Ce problème peut également être résolu en utilisant un nom complet. Par exemple, dans l'exemple ci-dessus, un programmeur pourrait écrire :

    java.lang.String s = ...
    java.lang.String s1 = s.substring(1);
  8. Homoglyphes : Si vous utilisez l'encodage UTF-8 pour vos fichiers sources, vous risquez de vous retrouver avec des identifiants qui semblent mêmes mais sont en réalité différents car ils contiennent des homoglyphes. Veuillez consulter cette page pour plus d'informations.

    Vous pouvez éviter cela en vous limitant à ASCII ou Latin-1 comme encodage du fichier source et en utilisant Java uxxxx pour échapper les autres caractères.


1 - Si vous faites voyez cela dans une exception d'exécution ou un message d'erreur, vous avez configuré votre IDE pour exécuter du code avec des erreurs de compilation, ou votre application est en cours de construction et de compilation au moment de l'exécution.
2 - Trois principes de base du génie civil : l'eau ne coule pas vers les hauteurs, les planches deviennent plus solides lorsqu'elles se font face et on ne peut pas pousser la corde.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal