method español error cannot java compiler-errors cannot-find-symbol

español - javac error cannot find symbol



¿Qué significa un error de compilación "No se puede encontrar el símbolo"? (10)

Por favor, 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 hace el programador para solucionar este error?

Esta pregunta está diseñada para ser una pregunta completa sobre los errores de compilación "no se puede encontrar el símbolo" en Java.


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

En primer lugar, es un error de compilación 1 . Esto significa que hay un problema en el código fuente de Java o un problema en la forma en que lo está compilando.

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 + , = , { , etc.
  • Identificadores: como Reader , i , toString , processEquibalancedElephants , y así sucesivamente.
  • Comentarios y espacios en blanco.

Un error "No se puede encontrar el símbolo" se refiere a los identificadores. Cuando se compila su código, el compilador necesita averiguar qué significa cada identificador en su código.

Un error "No se puede encontrar el símbolo" significa que el compilador no puede hacer esto. Su código parece estar refiriéndose a algo que el compilador no entiende.

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

Como primer orden, solo hay una causa. El compilador buscó en todos los lugares donde se debería definir el identificador, y no pudo encontrar la definición. Esto puede ser causado por una serie de cosas. Los comunes son los siguientes:

  • Para identificadores en general:
    • Tal vez escribiste el nombre incorrectamente; es decir, StringBiulder lugar de StringBuilder . Java no puede y no intentará compensar errores ortográficos o de escritura incorrectos.
    • Quizás tienes mal el caso; es decir, stringBuilder lugar de StringBuilder . Todos los identificadores de Java distinguen entre mayúsculas y minúsculas.
    • Tal vez usaste guiones poco apropiados; es decir, mystring y my_string son diferentes. (Si se adhiere a las reglas de estilo de Java, estará en gran medida protegido de este error ...)
    • Tal vez usted está tratando de usar algo que fue declarado "en otro lugar"; es decir, en un contexto diferente al que implícitamente le dijo al compilador que buscara. (¿Una clase diferente? ¿Un alcance diferente? ¿Un paquete diferente? ¿Una base de código diferente?)
  • Para identificadores que deberían referirse a variables:
    • Quizás te olvidaste de declarar la variable.
    • Quizás la declaración de la variable está fuera del alcance en el momento en que intentó usarla. (Ver ejemplo abajo)
  • Para 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 / ancestro.
    • Quizás esté intentando referirse a un método o campo que no existe (es decir, no se ha declarado) en el tipo que está utilizando; por ejemplo, "someString".push() 2 .
    • Tal vez usted está 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 te olvidaste de importar la clase.
    • Quizás utilizó importaciones "estrella", pero la clase no está definida en ninguno de los paquetes que importó.
    • Tal vez olvidaste una new como en:

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

  • Para los casos en los que el tipo o la instancia no parecen tener el miembro que esperaba que tuviera:

    • Tal vez haya declarado una clase anidada o un parámetro genérico que oculte el tipo que quería usar.
    • Tal vez usted está siguiendo una variable estática o instancia.
    • Quizás importaste el tipo equivocado; Por ejemplo, debido a la finalización de IDE o autocorrección.
    • Quizás esté utilizando (compilando en contra) la versión incorrecta de una API.
    • Tal vez se le olvidó lanzar su objeto a una subclase apropiada.

El problema es a menudo una combinación de lo anterior. Por ejemplo, tal vez "estrella" importó java.io.* y luego intentó usar la clase de Files ... que está en java.nio no java.nio O tal vez quisiste escribir el File ... que es una clase en java.io

Este es un ejemplo de cómo el alcance de una variable incorrecta puede llevar a un error "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 de "No se puede encontrar el símbolo" para i en la sentencia if . Aunque anteriormente declaramos i , esa declaración solo está dentro del alcance de la declaración for y su cuerpo. La referencia a i en la declaración if no puede ver esa declaración de i . Está fuera de alcance .

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

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

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

Esto le dará un error de compilación en la llamada de println que dice que no se puede encontrar. Pero (te oigo decir) ¡Lo declaré!

El problema es el punto y coma astuto ( ; ) antes del { . La sintaxis del lenguaje Java define un punto y coma en ese contexto como una declaración vacía . La declaración vacía se convierte entonces en el cuerpo del bucle for . Entonces ese código realmente significa esto:

for (int i = 0; i < 100; i++); // The previous and following are separate statements!! { System.out.println("i is " + i); }

El bloque { ... } NO es el cuerpo del bucle for , y por lo tanto, la declaración anterior de i en la instrucción for está fuera del alcance del bloque.

Este es otro ejemplo de error "No se puede encontrar el símbolo" causado por un error tipográfico.

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

A pesar de la declaración anterior, tmp en la expresión tmp(...) es errónea. El compilador buscará un método llamado tmp , y no encontrará uno. El tmp previamente declarado 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 programador en realidad había dejado de lado a un operador. Lo que quería escribir era esto:

int res = tmp * (a + b);

Hay otra razón por la que el compilador podría no encontrar un símbolo si está compilando desde la línea de comandos. Es posible que simplemente haya olvidado compilar o recompilar alguna otra clase. Por ejemplo, si tiene las clases Foo y Bar donde Foo usa Bar . Si nunca ha compilado Bar y ejecuta javac Foo.java , es probable que encuentre que el compilador no puede encontrar la Bar símbolos. La respuesta simple es compilar Foo y Bar juntos; por ejemplo, javac Foo.java Bar.java o javac *.java . O mejor aún, utilizar una herramienta de construcción de Java; por ejemplo, Ant, Maven, Gradle y así sucesivamente.

También hay otras causas más oscuras ... que trataré a continuación.

3. ¿Cómo soluciono estos errores?

En general, empiezas por averiguar qué causó el error de compilación.

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

Entonces piensas en lo que se supone que dice tu código. Luego, finalmente, averigua qué corrección necesita hacer a su código fuente para hacer lo que quiere.

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 compilador dice "No se puede encontrar el símbolo" para j . Hay muchas maneras en que podría "arreglar" que:

  • Podría cambiar el interno for for (int j = 1; j < 10; j++) - probablemente correcto.
  • Podría agregar una declaración para j antes del bucle for interno, o el bucle for externo, posiblemente correcto.
  • Podría cambiar de j a i en el bucle interno for - ¡probablemente esté mal!
  • y así.

El punto es que necesita comprender lo que su código está tratando de hacer para encontrar la solución correcta.

4. Causas oscuras

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

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

  2. No está recompilando : a veces sucede que los nuevos programadores de Java no entienden cómo funciona la cadena de herramientas de Java o no han implementado un "proceso de compilación" repetible; por ejemplo, utilizando un IDE, Ant, Maven, Gradle y así sucesivamente. En tal situación, el programador puede terminar persiguiendo su cola en busca de un error ilusorio que en realidad es causado por no compilar el código correctamente, y similares ...

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

  4. Problemas con el IDE : la gente ha reportado casos en los que su IDE se confunde y el compilador en el IDE no puede encontrar una clase que exista ... o la situación inversa.

    • Esto puede suceder si los cachés del IDE se desincronizan 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 donde Eclipse no maneja correctamente el árbol de "prueba" de Maven: vea esta respuesta .

  5. Redefiniendo las clases del sistema : he visto casos en los que el compilador 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 programador había creado su propia versión de String y que su versión de la clase no definía los métodos de substring .

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

  6. Homoglyphs: si usa la codificación UTF-8 para sus archivos de origen, es posible tener identificadores que parezcan iguales, pero de hecho son diferentes porque contienen homoglyphs. Vea esta página para más información.

    Puede evitarlo restringiéndose a ASCII o Latin-1 como la codificación del archivo fuente, y utilizando Java /uxxxx para otros caracteres.

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

2 - Los tres principios básicos de la Ingeniería Civil: el agua no fluye cuesta arriba, una tabla es más fuerte en su lado y no se puede empujar en una cuerda .


"No se puede encontrar" significa que, el compilador que no puede encontrar la variable, el método, la clase, etc. apropiados, si recibió ese mensaje de error, primero que todo, desea buscar la línea de código en la que recibe el mensaje de error ... Y luego lo hará capaz de encontrar qué variable, método o clase no se han definido antes de usarla. Después de la confirmación, inicialice esa variable, método o clase para usar más tarde ... 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 se puede encontrar" ... Definir e inicializar el valor para la variable ''nombre'' se puede eliminar ese error ... Realmente 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 se puede encontrar el método" o "no se puede encontrar la clase", al principio, defina una clase o un método y luego use eso.


Para obtener sugerencias, observe más de cerca el nombre de la clase que arroja un error y el número de línea, por ejemplo: Error de compilació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 java, por ejemplo, jdk7 vs 8. Verifique 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á utilizando IntelliJ

    File -> ''Invalidate Caches/Restart''

O

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

    compile project('':anotherProject'')

Y funcionó. HTH!


Si está obteniendo este error en la compilación en otro lugar, mientras su IDE dice que todo está perfectamente bien, compruebe que está utilizando 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 no existente en una versión anterior de Java causaría este error.


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

String s = String();

versus

String s = new String();


También puedes obtener este error si olvidaste una nueva como en:

int i = Integer (); ---- >> debe ser " new Integer () "

(Por eso me sale el error en mi caso)


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 compilará el código, pero maven dará "No se puede encontrar el símbolo".

Causa subyacente: Eclipse utiliza una ruta de compilación combinada para los árboles principal y de prueba. Desafortunadamente, no admite el uso de diferentes rutas de compilación para diferentes partes de un proyecto de Eclipse, que es lo que requiere Maven.

Solución:

  1. No definas tus dependencias de esa manera; es decir, no cometer este error
  2. Regularmente construye tu base de código usando Maven para que recojas este error antes de tiempo. Una forma de hacerlo es usar un servidor CI.

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. Recibía el siguiente error:

error: cannot find symbol

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


Un ejemplo más de ''Variable está fuera de alcance''

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.

Considere este código:

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

Eso es un código inválido. Debido a que ninguna de las variables nombradas message es visible fuera de su alcance respectivo, que serían los corchetes circundantes {} 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 te equivocarías.

Java no tiene operadores free() o de delete , por lo que tiene que depender del seguimiento del alcance de la variable para saber cuándo ya no se usan las variables (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 problema de alcance sería asignar previamente los valores de else a los nombres de variable en el alcance externo y luego reasignar si:

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