¿Qué significa un error de comstackción “No se puede encontrar el símbolo”?

Explique lo siguiente sobre el error “No se puede encontrar el símbolo”:

  • ¿Qué significa este error?
  • ¿Qué cosas pueden causar este error?
  • ¿Cómo va el progtwigdor a arreglar este error?

Esta pregunta está diseñada para ser una pregunta exhaustiva sobre los errores de comstackción “no se puede encontrar el símbolo” en Java.

1. ¿Qué significa un error “No se puede encontrar el símbolo”?

En primer lugar, es un error de comstackción 1 . Significa que hay un problema en el código fuente de Java o que hay un problema en la forma en que lo está comstackndo.

Su código fuente de Java consta de las siguientes cosas:

  • Palabras clave: como true , false , class , while , etc.
  • Literales: como 42 y 'X' y "Hi mum!" .
  • Operadores y otros tokens no alfanuméricos: como + , = , { , y así sucesivamente.
  • Identificadores: como Reader , i , toString , processEquibalancedElephants , etc.
  • Comentarios y espacios en blanco.

El error “No se puede encontrar el símbolo” se trata de los identificadores. Cuando se comstack su código, el comstackdor necesita determinar qué significa cada identificador en su código.

Un error “No se puede encontrar el símbolo” significa que el comstackdor no puede hacer esto. Su código parece referirse a algo que el comstackdor no comprende.

2. ¿Qué puede causar un error “No se puede encontrar el símbolo”?

Como primer orden, solo hay una causa. El comstackdor buscó en todos los lugares donde debería definirse el identificador y no pudo encontrar la definición. Esto podría deberse a varias cosas. Los comunes son los siguientes:

  • Para identificadores en general:
    • Tal vez deletreaste el nombre incorrectamente; es decir, StringBiulder lugar de StringBuilder . Java no puede ni intentará compensar los errores ortográficos o de tipeo.
    • Tal vez tienes el caso mal; es decir, stringBuilder lugar de StringBuilder . Todos los identificadores de Java distinguen mayúsculas de minúsculas.
    • Quizás usaste caracteres de subrayado inapropiados; es decir, mystring y my_string son diferentes. (Si te apegas a las reglas de estilo de Java, estarás ampliamente protegido contra este error …)
    • Tal vez estás tratando de usar algo que fue declarado “en otro lugar”; es decir, en un contexto diferente al que le has indicado implícitamente al comstackdor. (¿Una clase diferente? ¿Un scope diferente? ¿Un paquete diferente? ¿Una base de código diferente?)
  • Para identificadores que deben referirse a variables:
    • Quizás olvidaste declarar la variable.
    • Quizás la statement de la variable esté fuera de scope en el momento en que intentó usarla. (Ver ejemplo a continuación)
  • Para los identificadores que deberían ser nombres de métodos o campos:
    • Quizás esté intentando referirse a un método o campo heredado que no se declaró en las clases o interfaces padre / antecesor.
    • Tal vez estás tratando de usar un método como un campo, o viceversa; por ejemplo, "someString".length o someArray.length() .
  • Para identificadores que deberían ser nombres de clase:

    • Quizás olvidaste importar la clase.
    • Quizás utilizó importaciones “estrella”, pero la clase no está definida en ninguno de los paquetes que importó.
    • Quizás olvidaste una new como en:

       String s = String(); // should be 'new String()' 
  • Para los casos en que el tipo o instancia no parece tener el miembro que esperaba que tuviera:

    • Tal vez haya declarado una clase anidada o un parámetro genérico que sombree el tipo que quería usar.
    • Tal vez estés sombreando una variable estática o de instancia.
    • Quizás importaste el tipo incorrecto; por ejemplo, debido a la finalización del IDE o la autocorrección.
    • Quizás esté utilizando (comstackndo en contra) la versión incorrecta de una API.
    • Quizás olvidaste enviar tu objeto a una subclase apropiada.

El problema suele ser una combinación de lo anterior. Por ejemplo, tal vez “importó” java.io.* importado y luego intentó usar la clase Files … que está en java.nio not java.nio O quizás quisiste escribir File … que es una clase en java.io


A continuación, se muestra un ejemplo de cómo un ámbito de variable incorrecto puede generar un error de “No se puede encontrar el símbolo”:

 for (int i = 0; i < strings.size(); i++) { if (strings.get(i).equalsIgnoreCase("fnoord")) { break; } } if (i < strings.size()) { ... } 

Esto dará un error "No se puede encontrar el símbolo" para i en la statement if . Aunque declaramos i , esa statement solo está en el scope de la statement for y su cuerpo. La referencia a i en la sentencia if no puede ver esa statement de i . Está fuera de scope .

(Una corrección adecuada aquí podría ser mover la instrucción if dentro del ciclo o declarar i antes del inicio del ciclo).


Aquí hay un ejemplo que causa confusión cuando un error tipográfico conduce a un error aparentemente inexplicable "No se puede encontrar el símbolo":

 for (int i = 0; i < 100; i++); { System.out.println("i is " + i); } 

Esto le dará un error de comstackción en la llamada println diciendo que no puedo ser encontrado. Pero (lo oigo decir) ¡Lo declare!

El problema es el punto y coma furtivo antes del { . El lenguaje Java lo define como una statement vacía . Entonces ese código realmente significa esto:

 for (int i = 0; i < 100; i++); { System.out.println("i is " + i); } 

El { ... } bloque NO es el cuerpo del bucle for , por lo que la statement de i no está dentro del scope en el bloque.


Aquí hay otro ejemplo del error "No se puede encontrar el símbolo" que es causado por un error tipográfico.

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

A pesar de la statement anterior, el tmp en la expresión tmp(...) es erróneo. El comstackdor buscará un método llamado tmp , y no encontrará uno. El tmp declarado previamente está en el espacio de nombres para las variables, no en el espacio de nombres para los métodos.

En el ejemplo que encontré, el progtwigdor en realidad había omitido un operador. Lo que él quiso escribir fue esto:

 int res = tmp * (a + b); 

Hay otra razón por la cual el comstackdor puede no encontrar un símbolo si está comstackndo desde la línea de comando. Es posible que simplemente haya olvidado comstackr o recomstackr alguna otra clase. Por ejemplo, si tiene clases Foo y Bar donde Foo usa Bar . Si nunca compiló Bar y ejecuta javac Foo.java , es probable que encuentre que el comstackdor no puede encontrar el símbolo Bar . La respuesta simple es Foo y Bar juntos; por ejemplo javac Foo.java Bar.java o javac *.java . O mejor aún use una herramienta de comstackción Java; por ejemplo, Ant, Maven, Gradle, etc.

Hay algunas otras causas más oscuras también ... que trataré a continuación.

3. ¿Cómo soluciono estos errores?

En general, comienzas por averiguar qué causó el error de comstackción.

  • Mire la línea en el archivo indicado por el mensaje de error de comstackción.
  • Identifique de qué símbolo está hablando el mensaje de error.
  • Descubra por qué el comstackdor dice que no puede encontrar el símbolo; ¡véase más arriba!

Luego piensas en lo que se supone que tu código está diciendo. Luego, finalmente, resuelve qué corrección debe realizar en su código fuente para hacer lo que desea.

Tenga en cuenta que no todas las "correcciones" son correctas. Considera esto:

 for (int i = 1; i < 10; i++) { for (j = 1; j < 10; j++) { ... } } 

Supongamos que el comstackdor dice "No se puede encontrar el símbolo" para j . Hay muchas maneras en que podría "arreglar" eso:

  • Podría cambiar el interior for for (int j = 1; j < 10; j++) - probablemente sea correcto.
  • Podría agregar una statement para j antes del ciclo for interno, o el ciclo for externo, posiblemente correcto.
  • Podría cambiar j i en el ciclo for interno, ¡probablemente sea incorrecto!
  • y así.

El punto es que debes entender qué intenta hacer tu código para encontrar la solución correcta.

4. Causas oscuras

Aquí hay un par de casos en los que el "No se puede encontrar el símbolo" es aparentemente inexplicable ... hasta que miras más de cerca.

  1. Dependencias incorrectas : si está utilizando un IDE o una herramienta de comstackción que gestiona la ruta de comstackción y las dependencias del proyecto, es posible que haya cometido un error con las dependencias; por ejemplo, dejó fuera una dependencia, o seleccionó la versión incorrecta. Si está utilizando una herramienta de comstackción (Ant, Maven, Gradle, etc.), verifique el archivo de comstackción del proyecto. Si está utilizando un IDE, verifique la configuración de la ruta de comstackción del proyecto.

  2. No está recomstackndo : a veces sucede que los nuevos progtwigdores de Java no entienden cómo funciona la cadena de herramientas Java, o no han implementado un "proceso de comstackción" repetible; por ejemplo, usando un IDE, Ant, Maven, Gradle, etc. En tal situación, el progtwigdor puede terminar persiguiendo su cola en busca de un error ilusorio que en realidad es causado por no recomstackr el código correctamente, y cosas por el estilo ...

  3. Un problema de comstackción anterior : es posible que una comstackción anterior haya fallado de forma tal que haya un archivo JAR con clases faltantes. Tal falla normalmente se notaría si estuviera usando una herramienta de comstackción. Sin embargo, si obtiene archivos JAR de otra persona, depende de que se creen correctamente y de que detecten errores. Si sospecha esto, use tar -tvf para listar el contenido del archivo JAR sospechoso.

  4. Problemas de IDE : las personas han informado casos en los que su IDE se confunde y el comstackdor del IDE no puede encontrar una clase que existe ... o la situación inversa.

    • Esto puede suceder si las memorias caché del IDE no se sincronizan con el sistema de archivos. Hay formas específicas de IDE para arreglar eso.

    • Esto podría ser un error IDE. Por ejemplo, @Joel Costigliola describe un escenario en el que Eclipse no maneja correctamente un árbol de "prueba" de Maven: vea esta respuesta .

  5. Redefiniendo las clases del sistema : he visto casos en los que el comstackdor se queja de que la substring es un símbolo desconocido en algo como lo siguiente

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

    Resultó que el progtwigdor había creado su propia versión de String y que su versión de la clase no definía los métodos de una substring .

    Lección: ¡No defina sus propias clases con los mismos nombres que las clases de biblioteca comunes!

  6. Homoglifos: si usa la encoding UTF-8 para sus archivos fuente, es posible tener identificadores que se vean iguales, pero de hecho son diferentes porque contienen homoglíficos. Vea esta página para más información.

    Puede evitar esto restringiéndose a ASCII o Latin-1 como la encoding del archivo fuente, y usando Java \uxxxx para otros caracteres.


1 - Si, por casualidad, ve esto en una excepción de tiempo de ejecución o mensaje de error, entonces ha configurado su IDE para ejecutar código con errores de comstackción, o su aplicación está generando y comstackndo código ... en tiempo de ejecución.

También obtendrá este error si olvida una new :

 String s = String(); 

versus

 String s = new String(); 

Un ejemplo más de ‘Variable está fuera del scope’

Como ya he visto ese tipo de preguntas varias veces, tal vez un ejemplo más de lo que es ilegal, incluso si se siente bien.

Considera este código:

 if(somethingIsTrue()) { String message = "Everything is fine"; } else { String message = "We have an error"; } System.out.println(message); 

Ese es un código inválido. Debido a que ninguna de las variables llamadas message es visible fuera de su ámbito respectivo, que serían los corchetes {} en este caso.

Podría decir: “Pero una variable llamada mensaje se define de cualquier manera, por lo que el mensaje se define después de if “.

Pero estarías equivocado.

Java no tiene operadores free() o de delete , por lo que tiene que depender del seguimiento del scope de la variable para averiguar cuándo las variables ya no se utilizan (junto con las referencias a estas variables de causa).

Es especialmente malo si pensaste que hiciste algo bueno. He visto este tipo de error después de “optimizar” el código de esta manera:

 if(somethingIsTrue()) { String message = "Everything is fine"; System.out.println(message); } else { String message = "We have an error"; System.out.println(message); } 

“Oh, hay un código duplicado, vamos a sacar esa línea común” -> y ahí está.

La forma más común de lidiar con este tipo de problemas de scope sería preasignar los valores de los demás a los nombres de las variables en el ámbito externo y luego reasignarlos en caso de que:

 String message = "We have an error"; if(somethingIsTrue()) { message = "Everything is fine"; } System.out.println(message); 

Una forma de obtener este error en Eclipse:

  1. Defina una clase A en src/test/java .
  2. Defina otra clase B en src/main/java que use la clase A

Resultado: Eclipse comstackrá el código, pero maven mostrará “No se puede encontrar el símbolo”.

Causa subyacente: Eclipse está utilizando una ruta de comstackción combinada para los árboles principales y de prueba. Desafortunadamente, no es compatible con el uso de diferentes rutas de comstackción para diferentes partes de un proyecto de Eclipse, que es lo que Maven requiere.

Solución:

  1. No defina sus dependencias de esa manera; es decir, no cometas este error.
  2. Cree regularmente su base de código con Maven para que pueda detectar este error antes de tiempo. Una forma de hacerlo es usar un servidor de CI.

Si obtiene este error en la comstackción en otro lugar, mientras que su IDE dice que todo está perfectamente bien, entonces verifique que esté usando las mismas versiones de Java en ambos lugares.

Por ejemplo, Java 7 y Java 8 tienen diferentes API, por lo que llamar a una API inexistente en una versión anterior de Java provocaría este error.

“No se puede encontrar” significa eso, comstackdor que no puede encontrar la variable, el método, la clase, etc. adecuados … si obtuviste ese error de masaje, antes que nada, debes buscar la línea de código donde obtendrás un masaje de error … Y luego lo harás capaz de encontrar qué variable, método o clase no han definido antes de usarlo.Después de la confirmación, inicializar esa variable, método o clase se puede usar para más adelante requerir … Considere el siguiente ejemplo.

Crearé una clase de demostración e imprimiré un nombre …

 class demo{ public static void main(String a[]){ System.out.print(name); } } 

Ahora mira el resultado …

enter image description here

Ese error dice “el nombre de la variable no puede encontrar”. Definir e inicializar el valor para la variable “nombre” puede ser eliminado de ese error. De hecho, así,

 class demo{ public static void main(String a[]){ String name="smith"; System.out.print(name); } } 

Ahora mira la nueva salida …

enter image description here

Ok Resolvió con éxito ese error … Al mismo tiempo, si pudiera obtener “no puede encontrar el método” o “no puede encontrar clase”, al principio, defina una clase o método y luego de usarlo …

Yo también estaba recibiendo este error. (para lo cual busqué en Google y fui dirigido a esta página)

Problema: estaba llamando a un método estático definido en la clase de un proyecto A de una clase definida en otro proyecto B. Obtuve el siguiente error:

 error: cannot find symbol 

Solución: Lo resolví construyendo primero el proyecto donde se define el método y luego el proyecto desde el que se llamaba al método.

Para sugerencias, mire más de cerca el nombre de clase que arroja un error y el número de línea, por ejemplo: Error de comstackción [ERROR] \ applications \ xxxxx.java: [44,30] error: no se puede encontrar el símbolo

Otra causa es el método no compatible para la versión de Java, como jdk7 vs 8. Compruebe su% JAVA_HOME%

Puede haber varios escenarios como las personas han mencionado anteriormente. Un par de cosas que me han ayudado a resolver esto.

  1. Si estás usando IntelliJ

    File -> 'Invalidate Caches/Restart'

O

  1. La clase a la que se hizo referencia estaba en otro proyecto y esa dependencia no se agregó al archivo de comstackción de Gradle de mi proyecto. Entonces agregué la dependencia usando

    compile project(':anotherProject')

Y funcionó. HTH!

También puede obtener este error si declara con un tipo incorrecto, como:

Boolean en lugar de booleano

Entero en lugar de int

cadena en lugar de cadena