O que significa um erro “Não é possível encontrar o símbolo” ou “Não é possível resolver o símbolo”?

Sep 07 2014

Explique o seguinte sobre os erros "Não é possível encontrar o símbolo", "Não é possível resolver o símbolo" ou "Símbolo não encontrado":

  • O que eles querem dizer?
  • O que as coisas podem causar?
  • Como o programador os corrige?

Esta pergunta foi projetada para semear um Q&A abrangente sobre esses erros comuns de compilação em Java.

Respostas

441 StephenC Sep 07 2014 at 08:12

0. Existe alguma diferença entre os dois erros?

Na verdade não. "Não é possível encontrar o símbolo", "Não é possível resolver o símbolo" e "Símbolo não encontrado" significam a mesma coisa. Diferentes compiladores Java usam fraseologia diferente.

1. O que significa o erro "Não é possível encontrar o símbolo"?

Em primeiro lugar, é um erro de compilação 1 . Isso significa que tanto há um problema em seu código-fonte Java, ou há um problema na maneira que você está compilando-lo.

Seu código-fonte Java consiste no seguinte:

  • Palavras-chave: como true, false, class, while, e assim por diante.
  • Literais: como 42e 'X'e "Hi mum!".
  • Operadores e outros símbolos não alfanuméricos: como +, =, {e assim por diante.
  • Identificadores: como Reader, i, toString, processEquibalancedElephants, e assim por diante.
  • Comentários e espaço em branco.

Um erro "Não é possível encontrar o símbolo" é sobre os identificadores. Quando seu código é compilado, o compilador precisa descobrir o que significa cada identificador em seu código.

Um erro "Não é possível encontrar o símbolo" significa que o compilador não pode fazer isso. Seu código parece estar se referindo a algo que o compilador não entende.

2. O que pode causar um erro "Não é possível encontrar o símbolo"?

Como primeira ordem, existe apenas uma causa. O compilador procurou em todos os lugares onde o identificador deveria ser definido e não conseguiu encontrar a definição. Isso pode ser causado por uma série de coisas. Os mais comuns são os seguintes:

  • Para identificadores em geral:

    • Talvez você tenha soletrado o nome incorretamente; ou seja, em StringBiuldervez de StringBuilder. Java não pode e não tentará compensar erros ortográficos ou de digitação.
    • Talvez você tenha entendido errado o caso; ou seja, em stringBuildervez de StringBuilder. Todos os identificadores Java são sensíveis a maiúsculas e minúsculas.
    • Talvez você tenha usado sublinhados de forma inadequada; ou seja, mystringe my_stringsão diferentes. (Se você seguir as regras de estilo Java, estará amplamente protegido contra esse erro ...)
    • Talvez você esteja tentando usar algo que foi declarado "em outro lugar"; isto é, em um contexto diferente de onde você disse implicitamente ao compilador para olhar. (Uma classe diferente? Um escopo diferente? Um pacote diferente? Uma base de código diferente?)
  • Para identificadores que devem se referir a variáveis:

    • Talvez você tenha esquecido de declarar a variável.
    • Talvez a declaração da variável esteja fora do escopo no ponto em que você tentou usá-la. (Veja o exemplo abaixo)
  • Para identificadores que devem ser nomes de métodos ou campos:

    • Talvez você esteja tentando se referir a um método ou campo herdado que não foi declarado nas classes ou interfaces pai / ancestral.

    • Talvez você esteja tentando se referir a um método ou campo que não existe (ou seja, não foi declarado) no tipo que está usando; por exemplo, "someString".push()2 .

    • Talvez você esteja tentando usar um método como um campo, ou vice-versa; por exemplo "someString".lengthou someArray.length().

    • Talvez você esteja operando erroneamente em uma matriz em vez de um elemento de matriz; por exemplo

          String strings[] = ...
          if (strings.charAt(3)) { ... }
          // maybe that should be 'strings[0].charAt(3)'
      
  • Para identificadores que devem ser nomes de classe:

    • Talvez você tenha esquecido de importar a classe.

    • Talvez você tenha usado importações "estrela", mas a classe não está definida em nenhum dos pacotes que você importou.

    • Talvez você tenha esquecido um newcomo em:

          String s = String();  // should be 'new String()'
      
  • Para casos em que o tipo ou instância não parece ter o membro que você esperava:

    • Talvez você tenha declarado uma classe aninhada ou um parâmetro genérico que obscurece o tipo que você pretendia usar.
    • Talvez você esteja ocultando uma variável estática ou de instância.
    • Talvez você importou o tipo errado; por exemplo, devido à conclusão do IDE ou correção automática.
    • Talvez você esteja usando (compilando) a versão errada de uma API.
    • Talvez você tenha esquecido de lançar seu objeto em uma subclasse apropriada.

O problema geralmente é uma combinação dos itens acima. Por exemplo, talvez você tenha importado com "estrela" java.io.*e depois tentado usar a Filesclasse ... que java.nionão está java.io. Ou talvez você quisesse escrever File... que é uma classe em java.io.


Aqui está um exemplo de como o escopo de variável incorreto pode levar a um erro "Não é possível encontrar o símbolo":

List<String> strings = ...

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

Isso gerará um erro "Não é possível encontrar o símbolo" ina ifinstrução. Embora tenhamos declarado anteriormente i, essa declaração está apenas no escopo da forinstrução e seu corpo. A referência a ina ifdeclaração não pode ver essa declaração de i. Está fora do escopo .

(Uma correção apropriada aqui pode ser mover a ifinstrução dentro do loop ou declarar iantes do início do loop.)


Aqui está um exemplo que causa confusão em que um erro de digitação leva a um erro aparentemente inexplicável "Não é possível encontrar o símbolo":

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

Isso gerará um erro de compilação na printlnchamada dizendo que inão foi encontrado. Mas (eu ouço você dizer) eu declarei isso!

O problema é o ponto-e-vírgula sorrateiro ( ;) antes de {. A sintaxe da linguagem Java define um ponto-e-vírgula nesse contexto como uma instrução vazia . A instrução vazia então se torna o corpo do forloop. Então, esse código realmente significa isso:

for (int i = 0; i < 100; i++); 

// The previous and following are separate statements!!

{
    System.out.println("i is " + i);
}

O { ... }bloco NÃO é o corpo do forloop e, portanto, a declaração anterior de ina forinstrução está fora do escopo do bloco.


Aqui está outro exemplo de erro "Não é possível localizar o símbolo" causado por um erro de digitação.

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

Apesar da declaração anterior, o tmpna tmp(...)expressão está incorreto. O compilador procurará um método chamado tmpe não encontrará nenhum. O declarado anteriormente tmpestá no namespace para variáveis, não no namespace para métodos.

No exemplo que encontrei, o programador havia realmente omitido um operador. O que ele pretendia escrever era o seguinte:

int res = tmp * (a + b);

Há outro motivo pelo qual o compilador pode não encontrar um símbolo se você estiver compilando a partir da linha de comando. Você pode simplesmente ter esquecido de compilar ou recompilar alguma outra classe. Por exemplo, se você tem aulas Fooe Baronde Foousa Bar. Se você nunca compilou Bare o executa javac Foo.java, é provável que descubra que o compilador não consegue encontrar o símbolo Bar. A resposta simples é compilar Fooe Barjuntar; por exemplo javac Foo.java Bar.javaou javac *.java. Ou melhor ainda, use uma ferramenta de construção Java; por exemplo, Ant, Maven, Gradle e assim por diante.

Existem algumas outras causas mais obscuras também ... das quais tratarei a seguir.

3. Como faço para corrigir esses erros?

De modo geral, você começa descobrindo o que causou o erro de compilação.

  • Observe a linha no arquivo indicada pela mensagem de erro de compilação.
  • Identifique de qual símbolo a mensagem de erro está falando.
  • Descubra por que o compilador está dizendo que não consegue encontrar o símbolo; Veja acima!

Então você pensa sobre o que seu código deveria estar dizendo. Então, finalmente, você calcula que correção precisa fazer no código-fonte para fazer o que deseja.

Observe que nem todas as "correções" são corretas. Considere isto:

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

Suponha que o compilador diga "Não é possível encontrar o símbolo" para j. Há muitas maneiras de "consertar" isso:

  • Eu poderia mudar o interno forpara for (int j = 1; j < 10; j++)- provavelmente correto.
  • Eu poderia adicionar uma declaração para j antes do forloop interno ou do forloop externo - possivelmente correto.
  • Eu poderia mudar jpara ino forloop interno - provavelmente errado!
  • e assim por diante.

O ponto é que você precisa entender o que seu código está tentando fazer para encontrar a correção certa.

4. Causas obscuras

Aqui estão alguns casos em que o "Símbolo não encontrado" é aparentemente inexplicável ... até que você olhe mais de perto.

  1. Dependências incorretas : Se você estiver usando um IDE ou uma ferramenta de construção que gerencia o caminho de construção e as dependências do projeto, pode ter cometido um erro com as dependências; por exemplo, omitiu uma dependência ou selecionou a versão errada. Se você estiver usando uma ferramenta de construção (Ant, Maven, Gradle, etc), verifique o arquivo de construção do projeto. Se você estiver usando um IDE, verifique a configuração do caminho de construção do projeto.

  2. Você não está recompilando : às vezes acontece que novos programadores Java não entendem como a cadeia de ferramentas Java funciona ou não implementaram um "processo de construção" repetível; por exemplo, usando um IDE, Ant, Maven, Gradle e assim por diante. Em tal situação, o programador pode acabar perseguindo o próprio rabo à procura de um erro ilusório que é realmente causado por não recompilar o código corretamente e assim por diante ...

  3. Um problema de construção anterior : é possível que uma construção anterior tenha falhado de uma forma que forneceu um arquivo JAR com classes ausentes. Normalmente, essa falha seria observada se você estivesse usando uma ferramenta de construção. No entanto, se estiver obtendo arquivos JAR de outra pessoa, você dependerá da construção adequada deles e da detecção de erros. Se você suspeitar disso, use tar -tvfpara listar o conteúdo do arquivo JAR suspeito.

  4. Problemas de IDE : as pessoas relataram casos em que seu IDE fica confuso e o compilador no IDE não consegue encontrar uma classe existente ... ou a situação inversa.

  • Isso pode acontecer se o IDE tiver sido configurado com a versão errada do JDK.

  • Isso pode acontecer se os caches do IDE ficarem fora de sincronia com o sistema de arquivos. Existem maneiras específicas de IDE para consertar isso.

  • Isso pode ser um bug do IDE. Por exemplo, @Joel Costigliola descreve um cenário onde o Eclipse não lida com uma árvore de "teste" Maven corretamente: veja esta resposta .

  1. Problemas do Android : quando você estiver programando para Android e tiver erros "Não é possível encontrar o símbolo" relacionados R, esteja ciente de que os Rsímbolos são definidos pelo context.xmlarquivo. Verifique se o seu context.xmlarquivo está correto e no lugar correto e se o Rarquivo de classe correspondente foi gerado / compilado. Observe que os símbolos Java diferenciam maiúsculas de minúsculas, portanto, os IDs XML correspondentes também diferenciam maiúsculas de minúsculas.

    Outros erros de símbolo no Android são provavelmente devido a motivos mencionados anteriormente; por exemplo, dependências ausentes ou incorretas, nomes de pacotes incorretos, métodos ou campos que não existem em uma determinada versão da API, erros de ortografia / digitação e assim por diante.

  2. Redefinindo classes de sistema : vi casos em que o compilador reclama que substringé um símbolo desconhecido em algo como o seguinte

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

    Descobriu-se que o programador havia criado sua própria versão de Stringe que sua versão da classe não definia substringmétodos.

    Lição: Não defina suas próprias classes com os mesmos nomes das classes de biblioteca comuns!

  3. Homóglifos: se você usar a codificação UTF-8 para seus arquivos de origem, é possível ter identificadores que parecem iguais, mas são na verdade diferentes porque contêm homóglifos. Veja esta página para mais informações.

    Você pode evitar isso restringindo-se a ASCII ou Latin-1 como a codificação do arquivo de origem e usando \uxxxxescapes Java para outros caracteres.


1 - Se, por acaso, você não vê isso em uma exceção de tempo de execução ou mensagem de erro, então ou você configurou o IDE para executar código com erros de compilação, ou seu aplicativo está gerando e compilar o código .. em tempo de execução.

2 - Os três princípios básicos da Engenharia Civil: a água não sobe, uma prancha é mais forte do lado e não se pode empurrar um fio .

26 thinkterry Apr 17 2015 at 15:50

Você também receberá este erro se esquecer new:

String s = String();

versus

String s = new String();

porque a chamada sem a newpalavra - chave tentará procurar um método (local) chamado Stringsem argumentos - e essa assinatura de método provavelmente não está definida.

14 Jan Dec 06 2015 at 16:19

Mais um exemplo de 'Variável fora do escopo'

Como já vi esse tipo de pergunta algumas vezes, talvez mais um exemplo do que é ilegal, mesmo que pareça correto.

Considere este código:

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

Este é um código inválido. Porque nenhuma das variáveis ​​nomeadas messageé visível fora de seu respectivo escopo - que seriam os colchetes {}neste caso.

Você pode dizer: "Mas uma variável chamada mensagem é definida de qualquer maneira - então a mensagem é definida após if".

Mas você estaria errado.

Java não tem operadores free()ou delete, portanto, ele precisa contar com o rastreamento do escopo da variável para descobrir quando as variáveis ​​não são mais usadas (junto com as referências a essas variáveis ​​de causa).

É especialmente ruim se você pensou que fez algo bom. Já vi esse tipo de erro depois de "otimizar" o 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, há código duplicado, vamos puxar essa linha comum" -> e pronto.

A maneira mais comum de lidar com esse tipo de problema de escopo seria pré-atribuir os valores else aos nomes de variáveis ​​no escopo externo e então reatribuir se:

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

Uma maneira de obter esse erro no Eclipse:

  1. Defina uma classe Aem src/test/java.
  2. Defina outra classe Bem src/main/javaque usa classe A.

Resultado: o Eclipse irá compilar o código, mas o maven fornecerá "Não é possível encontrar o símbolo".

Causa subjacente: Eclipse está usando um caminho de construção combinado para as árvores principal e de teste. Infelizmente, ele não suporta o uso de diferentes caminhos de construção para diferentes partes de um projeto Eclipse, que é o que o Maven requer.

Solução:

  1. Não defina suas dependências dessa maneira; ou seja, não cometa esse erro.
  2. Crie regularmente sua base de código usando Maven para que você descubra esse erro antes do tempo. Uma maneira de fazer isso é usar um servidor de CI.
5 GT_hash Jun 30 2018 at 18:09

"Não é possível encontrar" significa que, compilador que não consegue encontrar a variável apropriada, método, classe etc ... se você recebeu aquela massagem de erro, primeiro de tudo você deseja encontrar a linha de código onde obter a massagem de erro ... E então você irá capaz de encontrar qual variável, método ou classe não definiu antes de usá-lo. Após a confirmação, inicializar essa variável, método ou classe pode ser usado para exigir posteriormente ... Considere o seguinte exemplo.

Vou criar uma classe de demonstração e imprimir um nome ...

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

Agora veja o resultado ..

Esse erro diz, "o nome da variável não pode ser encontrado" .. Definir e inicializar o valor para a variável 'nome' pode ser abolido esse erro .. Na verdade assim,

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

             String name="smith";

             System.out.print(name);
      }
}

Agora olhe para a nova saída ...

Ok, resolvido com sucesso esse erro .. Ao mesmo tempo, se você pudesse obter "não consigo encontrar método" ou "não consigo encontrar classe" algo, primeiro defina uma classe ou método e depois use isso ..

3 JonathanLin Mar 08 2016 at 12:58

Se você está recebendo este erro na construção em outro lugar, enquanto seu IDE diz que está tudo perfeitamente bem, então verifique se você está usando as mesmas versões de Java em ambos os lugares.

Por exemplo, Java 7 e Java 8 têm APIs diferentes, portanto, chamar uma API inexistente em uma versão anterior do Java causaria esse erro.

3 Ajay Oct 10 2019 at 19:07

RESOLVIDO

Usando IntelliJ

Selecione Build -> Rebuild Project irá resolvê-lo

2 DivyaJose Sep 28 2016 at 21:59

Eu também estava recebendo esse erro. (para o qual eu pesquisei e fui direcionado para esta página)

Problema: eu estava chamando um método estático definido na classe de um projeto A de uma classe definida em outro projeto B. Estava recebendo o seguinte erro:

error: cannot find symbol

Solução: Resolvi isso construindo primeiro o projeto onde o método é definido e depois o projeto de onde o método foi chamado.

2 UdayKiranPulipati Jan 24 2019 at 18:18

Se o caminho de construção do eclipse Java for mapeado para 7, 8 e nas propriedades do Maven do projeto pom.xml java.version for mencionada uma versão de Java superior (9,10,11, etc.,) do que 7,8, você precisa atualizar no pom. arquivo xml.

No Eclipse, se o Java é mapeado para Java versão 11 e em pom.xml é mapeado para Java versão 8. Atualize o suporte do Eclipse para Java 11 seguindo as etapas abaixo na Ajuda do Eclipse IDE -> Instalar Novo Software ->

Cole o seguinte link http://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With

ou

Adicionar (janela pop-up será aberta) ->

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

em seguida, atualize a versão Java nas propriedades Maven do arquivo pom.xml conforme abaixo

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

Por fim, clique com o botão direito no projeto Debug as -> Maven clean, etapas de construção do Maven

1 avp Aug 18 2018 at 08:45

Pode haver vários cenários, como as pessoas mencionaram acima. Algumas coisas que me ajudaram a resolver isso.

  1. Se você estiver usando IntelliJ

    File -> 'Invalidate Caches/Restart'

OU

  1. A classe que está sendo referenciada estava em outro projeto e essa dependência não foi adicionada ao arquivo de compilação do Gradle do meu projeto. Então, adicionei a dependência usando

    compile project(':anotherProject')

e funcionou. HTH!

1 ANILKUMAR Aug 07 2019 at 11:59

você compilou seu código usando compilar maven e então usou o teste maven para executá-lo funcionou bem. Agora, se você alterou algo em seu código e, em seguida, sem compilá-lo está executando, você obterá este erro.

Solução: Compile novamente e execute o teste. Para mim, funcionou assim.

1 VIPINKUMAR Sep 08 2019 at 14:50

No meu caso - tive que realizar as operações abaixo:

  1. Mova o context.xmlarquivo src/java/packagepara o resourcediretório (IntelliJ IDE)
  2. Limpe o targetdiretório.
Striker Sep 06 2017 at 19:47

Para dicas, olhe mais de perto o nome da classe que gera um erro e o número da linha, exemplo: Falha de compilação [ERROR] \ applications \ xxxxx.java: [44,30] erro: não é possível encontrar o símbolo

Uma outra causa é o método não suportado para a versão java, digamos jdk7 vs 8. Verifique seu% JAVA_HOME%

sakra Jul 20 2020 at 19:31

Recebemos o erro em um projeto Java configurado como uma compilação de vários projetos do Gradle. Descobriu-se que um dos subprojetos não tinha o plug-in Gradle Java Library . Isso evitou que os arquivos de classe do subprojeto fossem visíveis para outros projetos na construção.

Depois de adicionar o plug-in da biblioteca Java ao subprojeto build.gradleda seguinte maneira, o erro foi embora:

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

Resolvi esse erro assim ... A loucura do android. Eu tinha o nome do pacote como Adaptador e refatorei o nome para adaptador com um "a" em vez de "A" e resolvi o erro.