¿Qué significa el error "No se puede encontrar el símbolo" o "No se puede resolver el símbolo"?

Sep 07 2014

Explique lo siguiente acerca de los errores "No se puede encontrar el símbolo", "No se puede resolver el símbolo" o "Símbolo no encontrado":

  • ¿Qué quieren decir?
  • ¿Qué cosas las pueden causar?
  • ¿Cómo los arregla el programador?

Esta pregunta está diseñada para generar una completa sesión de preguntas y respuestas sobre estos errores de compilación comunes en Java.

Respuestas

441 StephenC Sep 07 2014 at 08:12

0. ¿Hay alguna diferencia entre los dos errores?

Realmente no. "No se puede encontrar el símbolo", "No se puede resolver el símbolo" y "Símbolo no encontrado" significan lo mismo. Los diferentes compiladores de Java utilizan una fraseología diferente.

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 o bien hay un problema en el código fuente de Java, o hay un problema en la forma en que se está compilando.

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

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

El error "No se puede encontrar el símbolo" se refiere a los identificadores. Cuando se compila su código, el compilador necesita averiguar qué significan todos y cada uno de los identificadores 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 referirse a algo que el compilador no comprende.

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 debería definirse el identificador y no pudo encontrar la definición. Esto podría deberse a varias cosas. Los más comunes son los siguientes:

  • Para identificadores en general:

    • Quizás escribiste el nombre incorrectamente; es decir, en StringBiulderlugar de StringBuilder. Java no puede y no intentará compensar la mala ortografía o los errores tipográficos.
    • Quizás entendiste mal el caso; es decir, en stringBuilderlugar de StringBuilder. Todos los identificadores de Java distinguen entre mayúsculas y minúsculas.
    • Quizás usó guiones bajos de manera inapropiada; es decir mystringy my_stringson diferentes. (Si se adhiere a las reglas de estilo Java, estará ampliamente protegido de este error ...)
    • Quizás esté intentando utilizar algo que se declaró "en otro lugar"; es decir, en un contexto diferente al que le ha dicho implícitamente al compilador que busque. (¿Una clase diferente? ¿Un alcance diferente? ¿Un paquete diferente? ¿Una base de código diferente?)
  • Para identificadores que deben hacer referencia a variables:

    • Quizás olvidó declarar la variable.
    • Quizás la declaración de variable esté fuera de alcance en el momento en que intentó usarla. (Ver ejemplo a continuación)
  • Para identificadores que deberían ser nombres de métodos o campos:

    • Quizás esté intentando hacer referencia a un método o campo heredado que no se declaró en las clases o interfaces padre / ancestro.

    • Quizás esté intentando hacer referencia a un método o campo que no existe (es decir, no ha sido declarado) en el tipo que está utilizando; por ejemplo, "someString".push()2 .

    • Quizás esté intentando utilizar un método como campo, o viceversa; p . ej . "someString".lengtho someArray.length().

    • Quizás esté operando por error en una matriz en lugar de un elemento de matriz; p.ej

          String strings[] = ...
          if (strings.charAt(3)) { ... }
          // maybe that should be 'strings[0].charAt(3)'
      
  • Para identificadores que deberían ser nombres de clases:

    • Quizás olvidó importar la clase.

    • Quizás usó importaciones "estrella", pero la clase no está definida en ninguno de los paquetes que importó.

    • Quizás olvidó un newcomo en:

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

    • Quizás ha declarado una clase anidada o un parámetro genérico que oculta el tipo que tenía la intención de usar.
    • Quizás está sombreando una variable estática o de instancia.
    • Quizás importó el tipo incorrecto; por ejemplo, debido a la finalización del IDE o la autocorrección.
    • Quizás esté utilizando (compilando contra) la versión incorrecta de una API.
    • Quizás olvidó enviar su objeto a una subclase apropiada.

El problema suele ser una combinación de los anteriores. Por ejemplo, tal vez usted "estrella" importado java.io.*y luego trató de utilizar la Filesclase ... que está en java.niono java.io. O tal vez quisiste escribir File... que es una clase en java.io.


A continuación, se muestra un ejemplo de cómo un alcance de variable incorrecto puede provocar un error "No se puede encontrar el símbolo":

List<String> strings = ...

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

Esto dará un error "No se puede encontrar el símbolo" ien la ifdeclaración. Aunque declaramos anteriormente i, esa declaración solo está dentro del alcance de la fordeclaración y su cuerpo. La referencia a ien la ifdeclaración no puede ver esa declaración de i. Está fuera de alcance .

(Una corrección apropiada aquí podría ser mover la ifdeclaración dentro del ciclo, o declarar iantes del inicio del ciclo).


Aquí hay un ejemplo que causa perplejidad donde 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 compilación en la printlnllamada diciendo que ino se puede encontrar. Pero (te escucho decir) ¡Yo lo declaré!

El problema es el punto y coma furtivo ( ;) 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 forbucle. 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 forbucle y, por lo tanto, la declaración anterior de ien la fordeclaración está fuera del alcance del bloque.


Aquí hay 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, el tmpen la tmp(...)expresión es erróneo. El compilador buscará un método llamado tmpy no lo encontrará. Lo declarado anteriormente tmpestá 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 había omitido 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 se haya olvidado de compilar o recompilar alguna otra clase. Por ejemplo, si tiene clases Fooy Bardónde se Foousa Bar. Si nunca ha compilado Bary lo ejecuta javac Foo.java, es probable que el compilador no pueda encontrar el símbolo Bar. La respuesta simple es compilar Fooy Barjuntar; p . ej . javac Foo.java Bar.javao javac *.java. O mejor aún, use una herramienta de construcción de Java; por ejemplo, Ant, Maven, Gradle y así sucesivamente.

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

3. ¿Cómo soluciono estos errores?

En términos generales, comienza por averiguar qué causó el error de compilación.

  • Mire la línea en el archivo indicada por el mensaje de error de compilación.
  • Identifique de qué símbolo se refiere el mensaje de error.
  • Descubra por qué el compilador dice que no puede encontrar el símbolo; ¡véase más arriba!

Luego piensa en lo que se supone que dice su código. Luego, finalmente, averigua qué corrección necesita hacer 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++) {
        ...
    }
}

Suponga que el compilador dice "No se puede encontrar el símbolo" para j. Hay muchas formas de "arreglar" eso:

  • Podría cambiar el interior fora for (int j = 1; j < 10; j++)... probablemente correcto.
  • Podría agregar una declaración j antes del forciclo interno o externo for, posiblemente correcto.
  • Podría cambiar ja ien el forbucle interno , ¡probablemente mal!
  • y así.

El punto es que debe comprender qué está tratando de hacer su código 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 miras más de cerca.

  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, omitió una dependencia o seleccionó la versión incorrecta. Si está utilizando una herramienta de compilación (Ant, Maven, Gradle, etc.), consulte 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á compilando : a veces sucede que los nuevos programadores de Java no comprenden cómo funciona la cadena de herramientas de Java, o no han implementado un "proceso de construcción" repetible; por ejemplo, usando un IDE, Ant, Maven, Gradle y así sucesivamente. En tal situación, el programador puede terminar persiguiéndose en busca de un error ilusorio que en realidad es causado por no volver a compilar el código correctamente, y cosas por el estilo ...

  3. Un problema de compilación anterior : es posible que una compilación anterior haya fallado de una manera que haya generado un archivo JAR con clases faltantes. Un error de este tipo normalmente se notaría si estuviera utilizando una herramienta de compilación. Sin embargo, si recibe archivos JAR de otra persona, depende de que se creen correctamente y de que noten errores. Si sospecha esto, utilice tar -tvfpara enumerar el contenido del archivo JAR sospechoso.

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

  • Esto podría suceder si el IDE se ha configurado con la versión de JDK incorrecta.

  • Esto podría suceder si los cachés del IDE no están sincronizados con el sistema de archivos. Hay formas específicas de IDE para solucionarlo.

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

  1. Problemas de Android : cuando esté programando para Android y tenga errores relacionados con "No se puede encontrar el símbolo" R, tenga en cuenta que los Rsímbolos están definidos por el context.xmlarchivo. Verifique que su context.xmlarchivo sea correcto y esté en el lugar correcto, y que Rse haya generado / compilado el archivo de clase correspondiente . Tenga en cuenta que los símbolos de Java distinguen entre mayúsculas y minúsculas, por lo que los identificadores XML correspondientes también distinguen entre mayúsculas y minúsculas.

    Es probable que otros errores de símbolos en Android se deban a razones mencionadas anteriormente; por ejemplo, dependencias faltantes o incorrectas, nombres de paquetes incorrectos, métodos o campos que no existen en una versión de API en particular, errores de ortografía / escritura, etc.

  2. Redefiniendo las clases del sistema : he visto casos en los que el compilador se queja de que substringes 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 Stringy que su versión de la clase no definía ningún substringmétodo.

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

  3. Homoglyphs: si usa codificación UTF-8 para sus archivos fuente, es posible tener identificadores que se vean iguales, pero que de hecho sean diferentes porque contienen homoglyphs. Consulte esta página para obtener más información.

    Puede evitar esto restringiéndose a ASCII o Latin-1 como codificación del archivo de origen y utilizando los \uxxxxescapes de Java para otros caracteres.


1 - Si, por ventura, que qué ver esto en una excepción de tiempo de ejecución o mensaje de error, ya sea que haya configurado el IDE para ejecutar código con errores de compilación, o su aplicación es la generación y compilación de 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 de lado y no se puede empujar una cuerda .

26 thinkterry Apr 17 2015 at 15:50

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

String s = String();

versus

String s = new String();

porque la llamada sin la newpalabra clave intentará buscar un método (local) llamado Stringsin argumentos, y es probable que la firma del método no esté definida.

14 Jan Dec 06 2015 at 16:19

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);

Ese es un código inválido. Porque ninguna de las variables nombradas messagees visible fuera de su ámbito 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 estarías equivocado.

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

Es especialmente malo si pensabas que hiciste algo bueno. He visto este tipo de error después de "optimizar" un código como este:

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

"Oh, hay código duplicado, saquemos 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 preasignar los valores else a los nombres de las variables en el alcance externo y luego reasignar si:

String message = "We have an error";
if(somethingIsTrue()) {
  message = "Everything is fine";
} 
System.out.println(message);
10 JoelCostigliola May 13 2016 at 17:09

Una forma de obtener este error en Eclipse:

  1. Definir una clase Aen src/test/java.
  2. Defina otra clase Ben src/main/javaesa clase de usos A.

Resultado: Eclipse compilará el código, pero maven dará "No se puede encontrar el símbolo".

Causa subyacente: Eclipse está utilizando una ruta de construcció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 Eclipse, que es lo que requiere Maven.

Solucion:

  1. No defina sus dependencias de esa manera; es decir, no cometa este error.
  2. Construya regularmente su base de código usando Maven para que pueda detectar este error temprano. Una forma de hacerlo es utilizar un servidor CI.
5 GT_hash Jun 30 2018 at 18:09

"No se puede encontrar" significa que, el compilador que no puede encontrar la variable, el método, la clase, etc. apropiados, si recibiste ese mensaje de error, en primer lugar, querrás encontrar la línea de código donde recibir el mensaje de error ... Y luego lo harás capaz de encontrar qué variable, método o clase no ha definido antes de usarlo. Después de la confirmación, inicialice esa variable, método o clase se puede usar para requerir 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 de la variable "nombre" puede eliminar ese error. De hecho, así,

class demo{ 
      public static void main(String a[]){

             String name="smith";

             System.out.print(name);
      }
}

Ahora mire la nueva salida ...

Ok Se resolvió exitosamente ese error ... Al mismo tiempo, si pudiera obtener algo "no se puede encontrar el método" o "no se puede encontrar la clase", primero, defina una clase o método y luego use eso ...

3 JonathanLin Mar 08 2016 at 12:58

Si recibe este error en la compilación en otro lugar, mientras que su IDE dice que todo está perfectamente bien, verifique 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 inexistente en una versión anterior de Java provocaría este error.

3 Ajay Oct 10 2019 at 19:07

RESUELTO

Usando IntelliJ

Seleccione Construir -> Reconstruir proyecto lo resolverá

2 DivyaJose Sep 28 2016 at 21:59

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

Problema: estaba llamando a un método estático definido en la clase de un proyecto A desde una clase definida en otro proyecto B. Recibí 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 donde se estaba llamando al método.

2 UdayKiranPulipati Jan 24 2019 at 18:18

Si la ruta de compilación Java de eclipse está asignada a 7, 8 y en las propiedades del Proyecto pom.xml Maven, se menciona java.version una versión superior de Java (9,10,11, etc.) que 7,8, necesita actualizar en pom. archivo xml.

En Eclipse, si Java está asignado a Java versión 11 y en pom.xml está asignado a Java versión 8. Actualice el soporte de Eclipse a Java 11 siguiendo los pasos a continuación en la Ayuda de eclipse IDE -> Instalar nuevo software ->

Pegue el siguiente enlace http://download.eclipse.org/eclipse/updates/4.9-P-builds en el trabajo con

o

Agregar (se abrirá una ventana emergente) ->

Name:Compatibilidad con Java 11 Location: http://download.eclipse.org/eclipse/updates/4.9-P-builds

luego actualice la versión de Java en las propiedades de Maven del archivo pom.xml como se muestra a continuación

<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

Finalmente haga clic derecho en el proyecto Depurar como -> Maven clean, Maven build steps

1 avp Aug 18 2018 at 08:45

Puede haber varios escenarios como la gente ha 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 hace referencia estaba en otro proyecto y esa dependencia no se agregó al archivo de compilación de Gradle de mi proyecto. Entonces agregué la dependencia usando

    compile project(':anotherProject')

Y funcionó. HTH!

1 ANILKUMAR Aug 07 2019 at 11:59

compiló su código usando la compilación de maven y luego usó la prueba de maven para ejecutarlo funcionó bien. Ahora, si cambió algo en su código y luego, sin compilarlo, lo está ejecutando, obtendrá este error.

Solución: compílelo nuevamente y luego ejecute la prueba. Para mí funcionó de esta manera.

1 VIPINKUMAR Sep 08 2019 at 14:50

En mi caso, tuve que realizar las siguientes operaciones:

  1. Mover context.xmlarchivo desde src/java/packageel resourcedirectorio (IntelliJ IDE)
  2. targetDirectorio limpio .
Striker Sep 06 2017 at 19:47

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

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

sakra Jul 20 2020 at 19:31

Obtuvimos el error en un proyecto Java que está configurado como una compilación multiproyecto de Gradle. Resultó que a uno de los subproyectos le faltaba el complemento Gradle Java Library . Esto impidió que los archivos de clases del subproyecto fueran visibles para otros proyectos en la compilación.

Después de agregar el complemento de la biblioteca de Java al subproyecto de build.gradlela siguiente manera, el error desapareció:

plugins {
    ...
    id 'java-library'
}
FelipeFranco Nov 20 2020 at 04:03

Resolví este error así ... La locura de Android. Tenía el nombre del paquete como Adaptador y refactoricé el nombre a adaptador con una "a" en lugar de "A" y resolví el error.