Erreur de compilation «Symbole introuvable»

1. Vue d'ensemble

Dans ce didacticiel, nous examinerons ce que sont les erreurs de compilation, puis expliquerons spécifiquement ce qu'est l'erreur «symbole introuvable» et comment elle est causée.

2. Erreurs de compilation

Pendant la compilation, le compilateur analyse et vérifie le code pour de nombreuses choses; types de référence, casts de types et déclarations de méthodes pour n'en nommer que quelques-uns. Cette partie du processus de compilation est importante car pendant cette phase nous aurons une erreur de compilation.

Fondamentalement, il existe trois types d'erreurs de compilation:

  • Nous pouvons avoir des erreurs de syntaxe . L'une des erreurs les plus courantes qu'un programmeur peut faire est d'oublier de mettre le point-virgule à la fin de l'instruction; d'autres oublient les importations, ne correspondent pas aux parenthèses ou omettent l'instruction de retour
  • Ensuite, il y a des erreurs de vérification de type. Il s'agit d'un processus de vérification de la sécurité des types dans notre code. Avec cette vérification, nous nous assurons que nous avons des types d'expressions cohérents. Par exemple, si nous définissons une variable de type int , nous ne devons jamais lui affecter une valeur double ou String
  • Pendant ce temps, il est possible que le compilateur plante . C'est très rare mais cela peut arriver. Dans ce cas, il est bon de savoir que notre code n'est peut-être pas un problème, mais qu'il s'agit plutôt d'un problème externe

3. Erreur «Impossible de trouver le symbole»

L'erreur «Impossible de trouver le symbole» survient principalement lorsque nous essayons d'utiliser une variable qui n'est pas définie ou déclarée dans notre programme.

Lorsque notre code se compile, le compilateur doit vérifier tous les identificateurs que nous avons. L'erreur «Impossible de trouver le symbole» signifie que nous faisons référence à quelque chose que le compilateur ne sait pas .

3.1. Qu'est-ce qui peut provoquer l' erreur «symbole introuvable» ?

En réalité, il n'y a qu'une seule cause: le compilateur n'a pas pu trouver la définition d'une variable que nous essayons de référencer.

Mais, il existe de nombreuses raisons pour lesquelles cela se produit. Pour nous aider à comprendre pourquoi, rappelons-nous en quoi consiste le code Java.

Notre code source Java se compose de:

  • Mots-clés: vrai, faux, classe, tandis que
  • Littéraux: nombres et texte
  • Opérateurs et autres jetons non alphanumériques: -, /, +, =, {
  • Identifiants: main , Reader , i , toString , etc.
  • Commentaires et espaces

4. Faute d'orthographe

Les problèmes les plus courants sont tous liés à l'orthographe. Si nous rappelons que tous les identifiants Java sont sensibles à la casse, nous pouvons voir que:

  • StringBiulder
  • stringBuilder
  • String_Builder

seraient toutes des manières différentes de faire référence de manière incorrecte à la classe StringBuilder .

5. Portée de l'instance

Cette erreur peut également se produire lors de l'utilisation de quelque chose qui a été déclaré en dehors de la portée de la classe.

Par exemple, disons que nous avons une classe Article qui appelle une méthode generateId :

public class Article { private int length; private long id; public Article(int length) { this.length = length; this.id = generateId(); } }

Mais, nous déclarons la méthode generateId dans une classe distincte:

public class IdGenerator { public long generateId() { Random random = new Random(); return random.nextInt(); } }

Avec cette configuration, le compilateur donnera une erreur «Impossible de trouver le symbole» pour generateId à la ligne 7 de l' extrait d' article . La raison en est que la syntaxe de la ligne 7 implique que la méthode generateId est déclarée dans Article .

Comme dans toutes les langues matures, il existe plusieurs façons de résoudre ce problème. Mais, une façon serait de construire IdGenerator dans la classe Article , puis d'appeler la méthode:

public class Article { private int length; private long id; public Article(int length) { this.length = length; this.id = new IdGenerator().generateId(); } }

6. Variables non définies

Parfois, nous oublions de déclarer la variable. Comme nous pouvons le voir dans l'extrait ci-dessous, nous essayons de manipuler la variable que nous n'avons pas déclarée, dans ce cas, le texte :

public class Article { private int length; // ... public void setText(String newText) { this.text = newText; // text variable was never defined } }

Nous résolvons ce problème en déclarant le texte variable de type String :

public class Article { private int length; private String text; // ... public void setText(String newText) { this.text = newText; } }

7. Portée variable

Lorsqu'une déclaration de variable est hors de portée au moment où nous avons essayé de l'utiliser, cela provoquera une erreur lors de la compilation. Cela se produit généralement lorsque nous travaillons avec des boucles.

Les variables à l'intérieur de la boucle ne sont pas accessibles en dehors de la boucle:

public boolean findLetterB(String text) { for (int i=0; i < text.length(); i++) { Character character = text.charAt(i); if (String.valueOf(character).equals("b")) { return true; } return false; } if (character == "a") { // <-- error! ... } }

L' instruction if devrait aller à l'intérieur de la boucle for si nous devons examiner davantage les caractères:

public boolean findLetterB(String text) { for (int i = 0; i < text.length(); i++) { Character character = text.charAt(i); if (String.valueOf(character).equals("b")) { return true; } else if (String.valueOf(character).equals("a")) { ... } return false; } }

8. Utilisation incorrecte de méthodes ou de champs

L'erreur «Impossible de trouver le symbole» se produira également si nous utilisons un champ comme méthode ou vice versa:

public class Article { private int length; private long id; private List texts; public Article(int length) { this.length = length; } // getters and setters }

Maintenant, si nous essayons de faire référence au champ des textes de l'article comme s'il s'agissait d'une méthode:

Article article = new Article(300); List texts = article.texts();

alors nous verrions l'erreur.

That's because the compiler is looking for a method called texts, which there isn't one.

Actually, there's a getter method that we can use instead:

Article article = new Article(300); List texts = article.getTexts();

Mistakenly operating on an array rather than an array element is also an issue:

for (String text : texts) { String firstLetter = texts.charAt(0); // it should be text.charAt(0) }

And so is forgetting the new keyword as in:

String s = String(); // should be 'new String()'

9. Package and Class Imports

Another problem is forgetting to import the class or package. For example, using a List object without importing java.util.List:

// missing import statement: // import java.util.List public class Article { private int length; private long id; private List texts; <-- error! public Article(int length) { this.length = length; } }

This code would not compile since the program doesn't know what List is.

10. Wrong Imports

Importing the wrong type, due to IDE completion or auto-correction is also a common issue.

Think of the situation when we want to use dates in Java. A lot of times we could import a wrong Date class, which doesn't provide methods and functionalities as other date classes that we might need:

Date date = new Date(); int year, month, day;

To get the year, month, or day for java.util.Date, we also need to import Calendar class and extract the information from there.

Simply invoking getDate() from java.util.Date won't work:

... date.getDay(); date.getMonth(); date.getYear();

Instead, we use the Calendar object:

... Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris")); cal.setTime(date); year = cal.get(Calendar.YEAR); month = cal.get(Calendar.MONTH); day = cal.get(Calendar.DAY_OF_MONTH);

However, if we have imported the LocalDate class, we wouldn't need additional code that provides us the information we need:

... LocalDate localDate=date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); year = localDate.getYear(); month = localDate.getMonthValue(); day = localDate.getDayOfMonth();

11. Conclusion

Les compilateurs travaillent sur un ensemble fixe de règles spécifiques à la langue. Si un code ne respecte pas ces règles, le compilateur ne peut pas effectuer un processus de conversion qui entraîne une erreur de compilation. Lorsque nous sommes confrontés à l'erreur de compilation «Impossible de trouver le symbole», la clé est d'identifier la cause.

À partir du message d'erreur, nous pouvons trouver la ligne de code où l'erreur se produit et quel élément est erroné. Connaître les problèmes les plus courants à l'origine de cette erreur rendra sa résolution très simple et rapide.