O que significa um erro de compilação "não consegue encontrar o símbolo"?

por favor explique o seguinte acerca do erro de "incapaz de encontrar o símbolo":

    O que significa este erro? Que coisas podem causar este erro? Como é que o programador corrige este erro?

esta questão é projetada para ser uma pergunta abrangente sobre erros de compilação de "cannot find symbol" em Java.

Author: Taryn, 2014-09-07

10 answers

1. O que significa um erro de "não encontrar o símbolo"?

Em primeiro lugar, trata-se de um erro de compilação1. Significa que ou existe um problema no seu código fonte Java, ou existe um problema na forma como o está a compilar.

O seu código fonte Java consiste nas seguintes coisas:

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

Um erro de" incapaz de encontrar o símbolo " é sobre os identificadores. Quando o seu código é compilado, o compilador precisa de descobrir o que cada identificador do seu código significa.

Um erro de "não encontrar o símbolo" significa que o compilador não pode fazer isto. O seu código parece estar a referir-se a algo que o compilador não compreende.

2. O que pode causar um erro de "não encontrar o símbolo"?

Como primeira ordem, só há uma causa. O compilador procurou em todos os lugares onde o identificador deveria ser definido, e não conseguiu encontrar a definição. Isto pode ser causado por uma série de coisas. Os mais comuns são os seguintes:
  • para identificadores em geral:
      Talvez tenhas escrito o nome incorrectamente; ou seja StringBiulder em vez de StringBuilder. Java não pode e não vai tentar compensar por erros de ortografia ou digitação.
  • Talvez tenhas percebido mal o caso, ou seja, em vez de StringBuilder. Todos os identificadores Java são sensíveis a maiúsculas.
  • talvez tenhas usado sublinhados inadequadamente; isto é, mystring e my_string são diferentes. (Se você se cingir às regras de estilo Java, você será amplamente protegido deste erro ...)
  • Talvez estejas a tentar usar algo que foi declarado "em algum outro lugar", ou seja, em um contexto diferente para onde você disse implicitamente ao compilador para olhar. (Uma classe diferente? Um âmbito diferente? Um pacote diferente? Uma base de código diferente?)
  • para identificadores que devem referir-se a variáveis:
      Talvez se tenha esquecido de declarar a variável.
  • Talvez a declaração variável esteja fora de alcance no momento em que tentou usá-la. (Ver exemplo abaixo)
  • para identificadores que devem ser métodos ou nomes de 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 esteja a tentar usar um método como campo, ou vice-versa; por exemplo "someString".length ou someArray.length().
  • Para identificadores que devem ser nomes de classe:

      Talvez te tenhas esquecido de importar a turma.
  • Talvez tenhas usado" star", mas a classe não está definida em nenhuma. dos pacotes que importaste.
  • Talvez te tenhas esquecido de um ...
    String s = String();  // should be 'new String()'
    
  • Para os casos em que o tipo ou instância não parece ter o membro que esperava que tivesse:

    • talvez tenha declarado uma classe aninhada ou um parâmetro genérico que sombras o tipo que pretendia usar.
    • Talvez estejas a seguir uma variável estática ou instância.
  • Talvez tenha importado o tipo errado.; por exemplo, devido à conclusão da IDE ou à auto-correcção.
  • talvez estejas a usar (compilar contra) a versão errada de uma API.
  • Talvez te tenhas esquecido de lançar o teu objecto para uma subclasse apropriada.

    O problema é muitas vezes uma combinação dos anteriores. Por exemplo, talvez você "star" importou java.io.* e então tentou usar a classe Files... que está em java.nio Não java.io. Ou talvez quisesses escrever ... que é {[86] } uma classe em java.io.


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

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

    Isto dará um erro de "não encontrar o símbolo" para i na declaração if. Embora tenhamos declarado anteriormente i, essa Declaração está apenas no âmbitopara a declaração for e para o seu corpo. A referência a i na declaração if não consegue ver essa Declaração de i. Está fora do âmbito de aplicação.

    A correção apropriada aqui pode ser mover a indicação if dentro do laço, ou declarar i antes do início do laço.)


    Aqui está um exemplo que causa perplexidade quando um erro de gralha leva a um aparentemente inexplicável erro de "não encontrar símbolo":
    for (int i = 0; i < 100; i++); {
        System.out.println("i is " + i);
    }
    

    Isto dar-lhe-á um erro de compilação na chamada println dizendo que i Não pode ser encontrado. Mas eu declarei-o!

    O problema é o ponto e vírgula sorrateiro antes do {. A linguagem Java define que é uma declaração vazia. Então esse código realmente significa isto:

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

    O bloco { ... } não é o corpo do laço for, por isso a declaração de i não está no âmbito no bloco.


    Aqui está outro exemplo de erro de" Cannot find symbol " que é causado por um erro tipográfico.

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

    Apesar da declaração anterior, a expressão tmp na expressão tmp(...) está errada. O compilador vai procurar um método chamado tmp, e não vai encontrar um. O tmp anteriormente declarado está no espaço de nomes para variáveis, não no espaço de nomes para métodos.

    No exemplo que encontrei, o programador deixou de fora um operador. O que ele queria escrever era isto:
    int res = tmp * (a + b);
    

    Existe outra razão pela qual o compilador pode não encontrar um símbolo se estiver a compilar a partir da linha de comandos. Você pode simplesmente ter esquecido de compilar ou recompilar alguma outra classe. Por exemplo, se classes Foo e Bar em que Foo se utiliza Bar. Se nunca compilou Bar e executa javac Foo.java, é provável que descubra que o compilador não consegue encontrar o símbolo Bar. A resposta simples é para Foo e Bar juntos; por exemplo javac Foo.java Bar.java ou javac *.java. Ou melhor ainda usar uma ferramenta de construção Java; por exemplo, Ant, Maven, Gradle e assim por diante.

    Também há outras causas mais obscuras ... que tratarei lá em baixo.

    3. Como posso corrigir esses erros ?

    De um modo geral, você começa por descobrir o que causou o erro de compilação.
    • veja a linha do ficheiro indicada pela mensagem de erro de compilação.
    • identifique o símbolo de que a mensagem de erro está a falar.
    • descubra porque o compilador está a dizer 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ê descobre que correção você precisa para Faça com que o seu código fonte faça o que quiser.

    Note que nem toda a "correcção" está correcta. Considere isto:

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

    Suponha que o compilador diz "não consegue encontrar o símbolo" para j. Há muitas maneiras que eu poderia "corrigir" que:

      Eu poderia mudar o interior para {[[40]} - provavelmente correto. Podia acrescentar uma declaração para j antes de o laço interior for, ou o laço exterior for - possivelmente correcto. Eu podia mudar para ... No laço interior, provavelmente errado! E assim por diante.
    A questão é que precisas de entender o que o teu código está a tentar fazer para encontrar a solução certa.

    4. Causas obscuras

    Aqui estão alguns casos em que o" não consegue encontrar o símbolo " é aparentemente inexplicável ... até olhares mais de perto.
    1. Dependências incorrectas: se estiver a usar um IDE ou uma ferramenta de compilação que gere a localização de compilação e dependências de projeto, você pode ter cometido um erro com as dependências; por exemplo, deixou de fora uma dependência, ou selecionou a versão errada. Se estiver a usar uma ferramenta de compilação (Ant, Maven, Gradle, etc), verifique o ficheiro de compilação do projecto. Se estiver a usar um IDE, verifique a configuração do caminho de compilação do projecto.

    2. Você não está recompilando: às vezes acontece que os novos programadores Java não entendem como a cadeia de ferramentas Java funciona, ou não implementaram um repetível "processo de construção"; por exemplo, usando uma IDE, Formiga, Maven, graxa e assim por diante. Em tal situação, o programador pode acabar perseguindo sua cauda em busca de um erro ilusório que é na verdade causado por não recompilar o código corretamente, e assim por diante ...

    3. Um problema de compilação anterior: é possível que uma compilação anterior tenha falhado de uma forma que tenha dado um ficheiro JAR com classes em falta. Tal falha seria tipicamente notada se você estivesse usando uma ferramenta de construção. Entanto se você está recebendo arquivos JAR de outra pessoa, você está dependente de eles construir corretamente, e notar erros. Se suspeitar disto, use tar -tvf para listar o conteúdo do ficheiro JAR suspeito.

    4. Questões IDE: as pessoas relataram casos em que a sua IDE fica confusa e o compilador na IDE não consegue encontrar uma classe que exista ... ou a situação inversa.

      • Isto pode acontecer se os esconderijos da IDE ficarem fora de sincronia com o ficheiro sistema. Há formas específicas de corrigir isso.

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

    5. Redefinindo classes do sistema : já 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);
      
      [84] programador tinha criado sua própria versão de String e que sua versão da classe não definia um método substring. Lição: não definas as tuas próprias aulas com os mesmos nomes que as classes comuns da biblioteca!
    6. Homógrafos: Se você usar a codificação UTF-8 para os arquivos de origem, é possível ter identificadores que olhar o mesmo, mas na verdade são diferentes porque eles contêm homógrafos. Ver esta página para mais informações.

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


    1 - Se, por acaso, você do ver isto numa excepção em tempo de execução ou numa mensagem de erro, então ou configurou o seu IDE para executar o código com erros de compilação, ou a sua aplicação está a gerar e a compilar o código .. no tempo de execução.

     301
    Author: Stephen C, 2018-08-29 12:06:45

    Também vais ter este erro se te esqueceres de um new:

    String s = String();
    

    Versus

    String s = new String();
    
     19
    Author: thinkterry, 2015-04-17 08:50:13

    Um outro exemplo de "variável está fora do âmbito de Aplicação'

    Como já vi esse tipo de perguntas algumas vezes, talvez mais um exemplo do que é ilegal, mesmo que possa parecer que está bem.

    Considere este código:

    if(somethingIsTrue()) {
      String message = "Everything is fine";
    } else {
      String message = "We have an error";
    }
    System.out.println(message);
    
    Isso é um código inválido. Porque nenhuma das variáveis chamadas message é visível fora do seu respectivo âmbito-que seriam os parêntesis circundantes {} neste caso. Pode-se dizer: "mas uma variável chamada a mensagem é definida de qualquer forma-então a mensagem é definida após o if". Mas estarias errado.

    Java não tem operadores free() ou delete, por isso tem de confiar no seguimento do âmbito da variável para descobrir quando as variáveis já não são usadas (juntamente com referências a estas variáveis de causa).

    É especialmente mau se pensamos que fizemos algo de bom. Eu vi esse tipo de erro depois de "otimizar" o código assim:
    if(somethingIsTrue()) {
      String message = "Everything is fine";
      System.out.println(message);
    } else {
      String message = "We have an error";
      System.out.println(message);
    }
    
    Há duplicados. Código, vamos puxar essa linha comum para fora " - > e lá ela.

    A maneira mais comum de lidar com este tipo de escopo-problema seria pré-atribuir os outros-valores aos nomes das variáveis no escopo externo e, em seguida, reatribuir em se:

    String message = "We have an error";
    if(somethingIsTrue()) {
      message = "Everything is fine";
    } 
    System.out.println(message);
    
     13
    Author: Jan, 2016-11-01 03:42:55

    Uma maneira de obter este erro no Eclipse:

    1. Define uma classe A em src/test/java.
    2. Define outra classe B em src/main/java que usa a classe A.
    Resultado: o Eclipse irá compilar o código, mas o maven irá dar "não consegue encontrar o símbolo".

    Causa subjacente: o Eclipse está a usar um caminho de construção combinado para as árvores principais 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 Maven requerer.

    Solução:

    1. Não defina as suas dependências dessa forma; ou seja, não cometa este erro.
    2. construa regularmente a sua base de código usando o Maven para que apanhe este erro mais cedo. Uma maneira de fazer isso é usar um servidor de CI.
     8
    Author: Joel Costigliola, 2016-07-30 01:09:42

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

    Por exemplo, Java 7 e Java 8 têm APIs diferentes, então chamar uma API inexistente em uma versão Java mais antiga causaria este erro.

     2
    Author: Jonathan Lin, 2016-03-08 05:58:27

    "Can not find"significa que, compilador que não consegue encontrar a variável apropriada, método, classe etc...se você tiver essa massagem erro, em primeiro lugar você quer encontrar a linha de código onde obter Massagem erro..E então você será capaz de encontrar que variável, método ou classe não têm definido antes de usá-lo.Após a confirmação inicializar que variável, método ou classe pode ser usado para necessidades posteriores...Considere o seguinte exemplo.

    Vou criar uma aula de demonstração e imprimir um nome...
    class demo{ 
          public static void main(String a[]){
                 System.out.print(name);
          }
    }
    
    Agora olhe para o resultado..

    enter image description here

    Esse erro diz, "o nome da variável não pode encontrar"..A definição e inicialização do valor da variável "nome" pode ser abolida..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...

    enter image description here

    OK resolveu isso com sucesso error..At ao mesmo tempo, se você pode obter "não pode encontrar método" ou "não pode encontrar classe" algo , no início,definir uma classe ou método e depois de usar isso..

     2
    Author: GT_hash, 2018-07-01 03:09:43
    Eu também estava a ter este erro. [para o qual eu pesquisei no Google e fui direcionado para esta página] [3]}

    Problema: estava a chamar um método estático definido na classe de um projecto a de uma classe definida noutro projecto B. Eu estava recebendo o seguinte erro:

    error: cannot find symbol
    

    Solução: resolvi isto primeiro construindo o projeto onde o método é definido, em seguida, o projeto de onde o método estava sendo chamado.

     0
    Author: Maria, 2016-10-07 14:09:44

    Para dicas, veja mais de perto o nome da classe que lança um erro e o número da linha, exemplo: Falha na compilação [Erro] \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 say jdk7 vs 8. Verifique o seu % JAVA_HOME %

     0
    Author: Striker, 2017-09-06 12:47:21
    Pode haver vários cenários, como as pessoas já mencionaram. Algumas coisas que me ajudaram a resolver isto.
    1. Se estiver a utilizar Intelij

      File -> 'Invalidate Caches/Restart'

    Ou

    1. A classe a ser referenciada estava noutro projecto e essa dependência não foi adicionada ao ficheiro de compilação do meu projecto. Então adicionei a dependência usando

      compile project(':anotherProject')

    E funcionou. HTH!
     0
    Author: avp, 2018-08-18 01:50:48

    Você também pode obter este erro se estiver a declarar com um tipo errado, como:

    Booleano em vez de booleano

    Inteiro em vez de inteiro

    Texto em vez de Texto

     -2
    Author: BlaCk HoLe, 2018-08-29 08:22:50