Maison > Questions et réponses > le corps du texte
Veuillez expliquer ce qui suit concernant les erreurs « symbole introuvable », « impossible de résoudre le symbole » ou « symbole introuvable » (en Java) :
Cette question vise à fournir une série de questions-réponses complètes sur ces erreurs de compilation courantes en Java.
P粉2037924682023-10-10 12:40:19
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粉9464374742023-10-10 11:07:06
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.)
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 :
class
、while
etc. true
、false
、42
、'X'
和 “嗨妈妈!”
. +
、=
、{
etc. Reader
、i
、toString
、processEquibalancedElephants
etc. 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.
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 :
StringBiulder
而不是 StringBuilder
. Java ne peut pas et ne tente pas de compenser les fautes d'orthographe ou les erreurs typographiques. stringBuilder
而不是 StringBuilder
. Tous les identifiants Java sont sensibles à la casse. mystring
和 my_string
est différent. (Si vous vous en tenez aux règles de style Java, vous éviterez largement cette erreur...) Pour les identifiants devant référencer des variables :
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".length
或 someArray.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 :
java.awt.List
而不是 java.util.List
. 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 » :
Liststrings = ... for (int i = 0; i < strings.size(); i++) { if (strings.get(i).equalsIgnoreCase("fnord")) { break; } } if (i < strings.size()) { ... }
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
的引用看不到 i
scope. La référence à i
dans l'instruction if
ne peut pas voir
i
. C'est hors de portéeif
语句移至循环内部,或在循环开始之前声明 i
.
.)
println
调用中给您一个编译错误,指出无法找到 i
Voici un exemple déroutant où une faute de frappe provoque une erreur apparemment inexplicable « symbole introuvable » :
for (int i = 0; i < 100; i++); { System.out.println("i is " + 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 < 100; i++); // The previous and following are separate statements!! { System.out.println("i is " + 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 Foo
和 Bar
,其中 Foo
使用 Bar
。如果您从未编译过 Bar
并且运行 javac Foo.java
,您很容易发现编译器找不到符号 Bar
。简单的答案是将 Foo
和 Bar
一起编译;例如javac Foo.java Bar.java
或 javac *.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.
De manière générale, vous devez d'abord découvrir quelle est la cause de l'erreur de compilation.
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 < 10; i++) { for (j = 1; j < 10; j++) { ... } }
Supposons que le compilateur affiche « symbole introuvable » pour j
. Il existe de nombreuses façons de "réparer" ce problème :
for
更改为 for (int j = 1; j < 10; j++)
- probablement vrai. for
循环或外部 for
循环之前添加一个 for j
for
ou la boucle externe for
for
循环中将 j
更改为 i
i
à l'intérieur de la boucle interne for
- probablement faux ! Le fait est que vous
devez 🎜 comprendre ce que votre code essaie de faire afin de trouver la bonne solution. 🎜Dans les quelques cas suivants, "symbole introuvable" semble déroutant... jusqu'à ce qu'on y regarde de plus près.
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.
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
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.
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.
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.)
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.
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
方法。我见过人们使用 System
、Scanner
. 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);
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.