0. Y a-t-il une différence entre les deux erreurs?
Pas vraiment. "Impossible de trouver le symbole" et "Impossible de résoudre le symbole" signifient la même chose. Certains compilateurs Java utilisent une phrase, et certains l'autre.
1. Que signifie une erreur "Symbole introuvable"?
Tout d'abord, il s'agit d'une erreur de compilation 1 . Cela signifie soit qu'il y a un problème dans votre code source Java, soit qu'il y a un problème dans la façon dont vous le compilez.
Votre code source Java se compose des éléments suivants:
- Mots - clés: comme
true
, false
, class
, while
et ainsi de suite.
- Littéraux: comme
42
et 'X'
et "Hi mum!"
.
- Les opérateurs et autres jetons non alphanumériques: comme
+
, =
, {
et ainsi de suite.
- Identifiants: comme
Reader
, i
, toString
, processEquibalancedElephants
et ainsi de suite.
- Commentaires et espaces.
Une erreur "Impossible de trouver le symbole" concerne les identificateurs. Lorsque votre code est compilé, le compilateur doit déterminer ce que signifie chaque identifiant dans votre code.
Une erreur "Impossible de trouver le symbole" signifie que le compilateur ne peut pas le faire. Votre code semble faire référence à quelque chose que le compilateur ne comprend pas.
2. Qu'est-ce qui peut provoquer une erreur "Symbole introuvable"?
En premier ordre, il n'y a qu'une seule cause. Le compilateur a recherché tous les endroits où l'identifiant devait être défini et il n'a pas pu trouver la définition. Cela pourrait être dû à un certain nombre de choses. Les plus courants sont les suivants:
- Pour les identifiants en général:
- Vous avez peut-être mal orthographié le nom; c'est à dire
StringBiulder
au lieu de StringBuilder
. Java ne peut pas et ne tentera pas de compenser les erreurs d'orthographe ou de frappe.
- Vous vous êtes peut-être trompé; c'est à dire
stringBuilder
au lieu de StringBuilder
. Tous les identificateurs Java sont sensibles à la casse.
- Vous avez peut-être utilisé des soulignements de manière inappropriée; c'est à dire
mystring
et my_string
sont différents. (Si vous respectez les règles de style Java, vous serez largement protégé contre cette erreur ...)
- Vous essayez peut-être d'utiliser quelque chose qui a été déclaré «ailleurs»; c'est-à-dire dans un contexte différent de celui où vous avez implicitement demandé au compilateur de regarder. (Une classe différente? Une portée différente? Un package différent? Une base de code différente?)
- Pour les identificateurs qui doivent faire référence à des variables:
- Vous avez peut-être oublié de déclarer la variable.
- Peut-être que la déclaration de variable est hors de portée au moment où vous avez essayé de l'utiliser. (Voir l'exemple ci-dessous)
Pour les identificateurs qui doivent être des noms de méthode ou de champ:
Pour les identificateurs qui doivent être des noms de classe:
Pour les cas où le type ou l'instance ne semble pas avoir le membre que vous attendiez qu'il ait:
- Vous avez peut-être déclaré une classe imbriquée ou un paramètre générique qui associe le type que vous vouliez utiliser.
- Vous observez peut-être une variable statique ou d'instance.
- Vous avez peut-être importé le mauvais type; par exemple en raison de l'achèvement de l'IDE ou de la correction automatique.
- Peut-être que vous utilisez (compilez) la mauvaise version d'une API.
- Vous avez peut-être oublié de transposer votre objet dans une sous-classe appropriée.
Le problème est souvent une combinaison de ce qui précède. Par exemple, vous avez peut-être importé une "étoile" java.io.*
, puis essayé d'utiliser la Files
classe ... qui ne l'est java.nio
pas java.io
. Ou peut-être que vous vouliez écrire File
... qui est une classe java.io
.
Voici un exemple de la façon dont une portée de variable incorrecte peut conduire à une erreur «Symbole introuvable»:
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
Cela donnera une erreur "Impossible de trouver le symbole" pour i
dans l' if
instruction. Bien que nous l'ayons déjà déclaré i
, cette déclaration n'a de portée que pour la for
déclaration et son corps. La référence à i
dans la if
déclaration ne peut pas voir cette déclaration de i
. C'est hors de portée .
(Une correction appropriée ici pourrait être de déplacer l' if
instruction à l'intérieur de la boucle ou de la déclarer i
avant le début de la boucle.)
Voici un exemple qui provoque la perplexité où une faute de frappe conduit à une erreur apparemment inexplicable "Symbole introuvable":
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
Cela vous donnera une erreur de compilation dans l' println
appel disant que i
introuvable. Mais (je vous entends dire) je l'ai déclaré!
Le problème est le point-virgule sournois ( ;
) avant le {
. La syntaxe du langage Java définit un point-virgule dans ce contexte comme une instruction vide . L'instruction vide devient alors le corps de la for
boucle. Donc, ce code signifie en fait ceci:
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
Le { ... }
bloc n'est PAS le corps de la for
boucle, et par conséquent la déclaration précédente de i
dans l' for
instruction est hors de portée dans le bloc.
Voici un autre exemple d'erreur «Impossible de trouver le symbole» provoquée par une faute de frappe.
int tmp = ...
int res = tmp(a + b);
Malgré la déclaration précédente, tmp
l' tmp(...)
expression est erronée. Le compilateur recherchera une méthode appelée tmp
et n'en trouvera pas. Le précédemment déclaré se tmp
trouve dans l'espace de noms pour les variables, pas dans l'espace de noms pour les méthodes.
Dans l'exemple que j'ai rencontré, le programmeur avait en fait omis un opérateur. Ce qu'il voulait écrire était le suivant:
int res = tmp * (a + b);
Il existe une autre raison pour laquelle le compilateur peut ne pas trouver de symbole si vous compilez à partir de la ligne de commande. Vous pourriez simplement avoir oublié de compiler ou recompiler une autre classe. Par exemple, si vous avez des classes Foo
et Bar
où les Foo
utilise Bar
. Si vous n'avez jamais compilé Bar
et que vous exécutez javac Foo.java
, vous risquez de constater que le compilateur ne peut pas trouver le symbole Bar
. La réponse simple est de compiler Foo
et Bar
ensemble; par exemple javac Foo.java Bar.java
ou javac *.java
. Ou mieux encore, utilisez un outil de construction Java; par exemple Ant, Maven, Gradle et ainsi de suite.
Il y a aussi d'autres causes plus obscures ... que je traiterai ci-dessous.
3. Comment puis-je corriger ces erreurs?
D'une manière générale, vous commencez par déterminer la cause de l'erreur de compilation.
- Regardez la ligne du fichier indiquée par le message d'erreur de compilation.
- Identifiez le symbole dont parle le message d'erreur.
- Découvrez pourquoi le compilateur dit qu'il ne peut pas trouver le symbole; voir au dessus!
Ensuite, vous pensez à ce que votre code est censé dire. Enfin, vous déterminez quelle correction vous devez apporter à votre code source pour faire ce que vous voulez.
Notez que toutes les «corrections» ne sont pas correctes. Considère ceci:
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
Supposons que le compilateur indique "Impossible de trouver le symbole" pour j
. Il y a plusieurs façons de "corriger" cela:
- Je pouvais changer le intérieur
for
à for (int j = 1; j < 10; j++)
- probablement correct.
- Je pourrais ajouter une déclaration pour
j
avant la for
boucle interne ou la for
boucle externe - peut-être correcte.
- Je pouvais changer
j
à i
la intérieur for
boucle - probablement faux!
- etc.
Le fait est que vous devez comprendre ce que votre code essaie de faire afin de trouver le bon correctif.
4. Causes obscures
Voici quelques cas où le "Symbole introuvable" est apparemment inexplicable ... jusqu'à ce que vous regardiez de plus près.
Dépendances incorrectes : si vous utilisez un IDE ou un outil de génération qui gère le chemin de génération et les dépendances du projet, vous avez peut-être fait une erreur avec les dépendances; par exemple, laissé de côté une dépendance ou sélectionné la mauvaise version. Si vous utilisez un outil de construction (Ant, Maven, Gradle, etc.), vérifiez le fichier de construction du projet. Si vous utilisez un IDE, vérifiez la configuration du chemin de génération du projet.
Vous n'êtes pas en train de recompiler : il arrive parfois que les nouveaux programmeurs Java ne comprennent pas comment fonctionne la chaîne d'outils Java ou n'ont pas mis en œuvre un "processus de construction" reproductible; par exemple en utilisant un IDE, Ant, Maven, Gradle et ainsi de suite. Dans une telle situation, le programmeur peut finir par courir après sa queue à la recherche d'une erreur illusoire qui est en fait causée par la non-recompilation correcte du code, etc.
Un problème de version antérieure : il est possible qu'une version antérieure ait échoué d'une manière qui a donné un fichier JAR avec des classes manquantes. Un tel échec serait généralement remarqué si vous utilisiez un outil de construction. Cependant, si vous obtenez des fichiers JAR de quelqu'un d'autre, vous dépendez de leur construction correcte et de la détection d'erreurs. Si vous suspectez cela, utilisez tar -tvf
pour répertorier le contenu du fichier JAR suspect.
Problèmes liés à l'IDE : des personnes ont signalé des cas où leur IDE est confus et le compilateur de l'EDI ne peut pas trouver une classe qui existe ... ou la situation inverse.
Cela peut se produire si l'IDE a été configuré avec la mauvaise version de JDK.
Cela peut se produire si les caches de l'EDI sont désynchronisés avec le système de fichiers. Il existe des moyens spécifiques à l'IDE pour résoudre ce problème.
Cela pourrait être un bogue IDE. Par exemple, @Joel Costigliola décrit un scénario où Eclipse ne gère pas correctement une arborescence de "test" Maven: voir cette réponse .
Problèmes Android : lorsque vous programmez pour Android et que vous rencontrez des erreurs "Impossible de trouver le symbole" R
, sachez que les R
symboles sont définis par le context.xml
fichier. Vérifiez que votre context.xml
fichier est correct et au bon endroit, et que le R
fichier de classe correspondant a été généré / compilé. Notez que les symboles Java sont sensibles à la casse, donc les identifiants XML correspondants sont également sensibles à la casse.
D'autres erreurs de symbole sur Android sont probablement dues à des raisons précédemment mentionnées; par exemple, des dépendances manquantes ou incorrectes, des noms de packages, des méthodes ou des champs incorrects qui n'existent pas dans une version particulière de l'API, des fautes d'orthographe / de frappe, etc.
Redéfinir les classes système : j'ai vu des cas où le compilateur se plaint que substring
c'est un symbole inconnu dans quelque chose comme ce qui suit
String s = ...
String s1 = s.substring(1);
Il s'est avéré que le programmeur avait créé sa propre version de String
et que sa version de la classe n'avait pas défini de substring
méthode.
Leçon: Ne définissez pas vos propres classes avec les mêmes noms que les classes de bibliothèque courantes!
Homoglyphes: si vous utilisez le codage UTF-8 pour vos fichiers source, il est possible d'avoir des identifiants qui se ressemblent , mais qui sont en fait différents car ils contiennent des homoglyphes. Consultez cette page pour plus d'informations.
Vous pouvez éviter cela en vous limitant à ASCII ou Latin-1 comme codage du fichier source et en utilisant des \uxxxx
échappements Java pour d'autres caractères.
1 - Si, par hasard, vous ne voyez cela à une exception d'exécution ou un message d'erreur, soit vous avez configuré votre IDE pour exécuter du code avec des erreurs de compilation, ou votre application génère et la compilation du code .. lors de l' exécution.
2 - Les trois principes de base du génie civil: l'eau ne coule pas en amont, une planche est plus solide sur le côté et vous ne pouvez pas pousser sur une corde .
println
dans leSystem.out.println
cas placé au niveau de la classe sous compilateur standard nous donnerait<identifier> expected
( démo ) mais IntelliJ nous verronsCannot resolve symbol 'println'
( démo ).Vous obtiendrez également cette erreur si vous oubliez
new
:contre
car l'appel sans le
new
mot clé essaiera de rechercher une méthode (locale) appeléeString
sans arguments - et cette signature de méthode n'est probablement pas définie.la source
Un autre exemple de «Variable est hors de portée»
Comme j'ai déjà vu ce genre de questions à plusieurs reprises, peut-être un autre exemple de ce qui est illégal même si cela peut sembler correct.
Considérez ce code:
C'est un code invalide. Parce qu'aucune des variables nommées
message
n'est visible en dehors de leur portée respective - qui serait les crochets environnants{}
dans ce cas.Vous pourriez dire: "Mais une variable nommée message est définie de toute façon - donc le message est défini après le
if
".Mais tu aurais tort.
Java n'a pas d' opérateurs
free()
oudelete
, donc il doit s'appuyer sur le suivi de la portée des variables pour savoir quand les variables ne sont plus utilisées (ainsi que les références à ces variables de cause).C'est particulièrement mauvais si vous pensiez avoir fait quelque chose de bien. J'ai vu ce genre d'erreur après avoir "optimisé" du code comme ceci:
"Oh, il y a du code en double, retirons cette ligne commune" -> et là, c'est tout.
La façon la plus courante de gérer ce type de problème de portée serait de pré-affecter les valeurs else aux noms de variables dans la portée extérieure, puis de les réaffecter si:
la source
final
.Une façon d'obtenir cette erreur dans Eclipse:
A
danssrc/test/java
.B
danssrc/main/java
cette classe utilisationsA
.Résultat: Eclipse compilera le code, mais maven donnera "Symbole introuvable".
Cause sous-jacente: Eclipse utilise un chemin de génération combiné pour les arborescences principale et de test. Malheureusement, il ne prend pas en charge l'utilisation de chemins de génération différents pour différentes parties d'un projet Eclipse, ce dont Maven a besoin.
Solution :
la source
"Impossible de trouver" signifie que, compilateur qui ne peut pas trouver la variable, la méthode, la classe etc ... si vous avez obtenu ce massage d'erreur, tout d'abord vous voulez trouver la ligne de code où obtenir le massage d'erreur .. Et puis vous capable de trouver quelle variable, méthode ou classe n'a pas défini avant de l'utiliser. Après confirmation, initialisez cette variable, méthode ou classe pour une utilisation ultérieure ... Considérez l'exemple suivant.
Je vais créer une classe de démonstration et imprimer un nom ...
Regardez maintenant le résultat ..
Cette erreur indique "le nom de la variable ne peut pas être trouvé". La définition et l'initialisation de la valeur de la variable "nom" peuvent être supprimées. En fait, comme ceci,
Regardez maintenant la nouvelle sortie ...
Ok Résolu cette erreur avec succès .. En même temps, si vous pouviez obtenir quelque chose "ne peut pas trouver la méthode" ou "ne peut pas trouver la classe", dans un premier temps, définissez une classe ou une méthode et après utilisation cela ..
la source
Si vous obtenez cette erreur dans la build ailleurs, alors que votre IDE dit que tout va parfaitement bien, vérifiez que vous utilisez les mêmes versions de Java aux deux endroits.
Par exemple, Java 7 et Java 8 ont des API différentes, donc appeler une API inexistante dans une ancienne version Java provoquerait cette erreur.
la source
Moi aussi, je recevais cette erreur. (pour lequel j'ai googlé et j'ai été dirigé vers cette page)
Problème: j'appelais une méthode statique définie dans la classe d'un projet A à partir d'une classe définie dans un autre projet B. J'obtenais l'erreur suivante:
Solution: J'ai résolu ce problème en créant d'abord le projet où la méthode est définie, puis le projet d'où la méthode était appelée.
la source
Si le chemin de construction de l'éclipse Java est mappé à 7, 8 et dans le projet pom.xml, les propriétés Maven java.version sont mentionnées dans une version Java supérieure (9,10,11, etc.) à 7,8, vous devez mettre à jour dans pom. fichier xml.
Dans Eclipse, si Java est mappé à Java version 11 et dans pom.xml, il est mappé à Java version 8. Mettez à jour la prise en charge d'Eclipse vers Java 11 en suivant les étapes ci-dessous dans l'aide IDE eclipse -> Installer un nouveau logiciel ->
Collez le lien suivant http://download.eclipse.org/eclipse/updates/4.9-P-builds au travail avec
ou
Ajouter (une fenêtre contextuelle s'ouvrira) ->
Name:
Prise en charge de Java 11Location:
http://download.eclipse.org/eclipse/updates/4.9-P-buildspuis mettez à jour la version Java dans les propriétés Maven du fichier pom.xml comme ci-dessous
Enfin, faites un clic droit sur le projet Debug as -> Maven clean, Maven build steps
la source
RESOLU
Sélectionnez Build -> Rebuild Project le résoudra
la source
Il peut y avoir différents scénarios comme les gens l'ont mentionné ci-dessus. Un couple de choses qui m'ont aidé à résoudre ce problème.
Si vous utilisez IntelliJ
File -> 'Invalidate Caches/Restart'
OU
La classe référencée se trouvait dans un autre projet et cette dépendance n'a pas été ajoutée au fichier de génération Gradle de mon projet. J'ai donc ajouté la dépendance en utilisant
compile project(':anotherProject')
et ça a marché. HTH!
la source
vous avez compilé votre code à l'aide de la compilation maven, puis utilisé le test maven pour l'exécuter a bien fonctionné. Maintenant, si vous avez modifié quelque chose dans votre code et que sans le compiler, vous l'exécutez, vous obtiendrez cette erreur.
Solution: compilez-le à nouveau, puis exécutez le test. Pour moi, cela a fonctionné de cette façon.
la source
Dans mon cas - j'ai dû effectuer les opérations ci-dessous:
context.xml
fichier desrc/java/package
vers leresource
répertoire (IntelliJ IDE)target
Répertoire propre .la source
Pour obtenir des conseils, examinez de plus près le nom du nom de classe qui génère une erreur et le numéro de ligne, par exemple: Échec de la compilation [ERREUR] \ applications \ xxxxx.java: [44,30] erreur: impossible de trouver le symbole
Une autre cause est la méthode non prise en charge de la version java, par exemple jdk7 vs 8. Vérifiez votre% JAVA_HOME%
la source