Explique lo siguiente sobre el error “No se puede encontrar el símbolo”:
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.
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:
true
, false
, class
, while
, etc. 42
y 'X'
y "Hi mum!"
. +
, =
, {
, y así sucesivamente. Reader
, i
, toString
, processEquibalancedElephants
, etc. 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.
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:
StringBiulder
lugar de StringBuilder
. Java no puede ni intentará compensar los errores ortográficos o de tipeo. stringBuilder
lugar de StringBuilder
. Todos los identificadores de Java distinguen mayúsculas de minúsculas. mystring
y my_string
son diferentes. (Si te apegas a las reglas de estilo de Java, estarás ampliamente protegido contra este error …) "someString".length
o someArray.length()
. Para identificadores que deberían ser nombres de clase:
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:
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.
En general, comienzas por averiguar qué causó el error de comstackción.
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:
for
for (int j = 1; j < 10; j++)
- probablemente sea correcto. j
antes del ciclo for
interno, o el ciclo for
externo, posiblemente correcto. j
i
en el ciclo for
interno, ¡probablemente sea incorrecto! El punto es que debes entender qué intenta hacer tu código para encontrar la solución correcta.
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.
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.
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 ...
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.
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 .
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!
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:
A
en src/test/java
. 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:
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 …
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 …
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.
Si estás usando IntelliJ
File -> 'Invalidate Caches/Restart'
O
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