0. Existe alguma diferença entre os dois erros?
Na verdade não. "Não é possível encontrar o símbolo" e "Não é possível resolver o símbolo" significam a mesma coisa. Alguns compiladores Java usam uma frase e outros a outra.
1. O que significa um 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
42
e '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 no 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, há 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 várias coisas. Os mais comuns são os seguintes:
- Para identificadores em geral:
- Talvez você tenha soletrado o nome incorretamente; ou seja, em
StringBiulder
vez de StringBuilder
. Java não pode e não tentará compensar erros ortográficos ou de digitação incorretos.
- Talvez você tenha entendido errado o caso; ou seja, em
stringBuilder
vez de StringBuilder
. Todos os identificadores Java diferenciam maiúsculas de minúsculas.
- Talvez você tenha usado sublinhados inadequadamente; ou seja,
mystring
e my_string
são diferentes. (Se você seguir as regras do estilo Java, estará amplamente protegido contra esse erro ...)
- Talvez você esteja tentando usar algo que foi declarado "em outro lugar"; ou seja, em um contexto diferente daquele em que você implicitamente disse ao compilador para procurar. (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 interfaces ou classes 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 você está usando; por exemplo
"someString".push()
2 .
- Talvez você esteja tentando usar um método como um campo ou vice-versa; por exemplo
"someString".length
ou someArray.length()
.
Talvez você esteja operando por engano em uma matriz em vez de em um elemento da 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:
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 oculta o tipo que você pretendia usar.
- Talvez você esteja sombreando uma variável estática ou de instância.
- Talvez você tenha importado o tipo errado; por exemplo, devido à conclusão ou correção automática do IDE.
- 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 estrela" importado java.io.*
e depois tentou usar a Files
classe ... que java.nio
não está java.io
. Ou talvez você pretendesse escrever File
... que é uma aula java.io
.
Aqui está um exemplo de como o escopo 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 fornecerá um erro "Não é possível encontrar o símbolo" i
na if
instrução. Embora tenhamos declarado anteriormente i
, essa declaração está apenas no escopo da for
declaração e de seu corpo. A referência a i
na if
declaração não pode ver essa declaração de i
. Está fora do escopo .
(Uma correção apropriada aqui pode ser mover a if
instrução para dentro do loop ou declarar i
antes do início do loop.)
Aqui está um exemplo que causa perplexidade 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 println
chamada dizendo que i
não pode ser encontrado. Mas (eu ouvi você dizer) eu declarei!
O problema é o ponto e vírgula furtivo ( ;
) antes do {
. A sintaxe da linguagem Java define um ponto-e-vírgula nesse contexto como uma instrução vazia . A declaração vazia se torna o corpo do for
loop. Portanto, 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 for
loop, e, portanto, a declaração anterior de i
na for
declaração é fora do escopo no bloco.
Aqui está outro exemplo de erro "Não é possível encontrar o símbolo" causado por um erro de digitação.
int tmp = ...
int res = tmp(a + b);
Apesar da declaração anterior, tmp
a tmp(...)
expressão está incorreta. O compilador procurará um método chamado tmp
e não o encontrará. O declarado anteriormente tmp
está no espaço de nomes para variáveis, não no espaço de nomes para métodos.
No exemplo que me deparei, o programador havia deixado de fora um operador. O que ele pretendia escrever era o seguinte:
int res = tmp * (a + b);
Há outra razão pela qual o compilador pode não encontrar um símbolo se você estiver compilando na linha de comando. Você pode simplesmente ter esquecido de compilar ou recompilar alguma outra classe. Por exemplo, se você tem classes Foo
e Bar
onde Foo
usa Bar
. Se você nunca compilou Bar
e executou javac Foo.java
, é provável que descubra que o compilador não pode encontrar o símbolo Bar
. A resposta simples é compilar Foo
e Bar
juntos; por exemplo javac Foo.java Bar.java
ou javac *.java
. Ou melhor ainda, use uma ferramenta de construção Java; por exemplo, Ant, Maven, Gradle e assim por diante.
Existem outras causas mais obscuras também ... com as quais tratarei abaixo.
3. Como faço para corrigir esses erros?
De um modo geral, você começa descobrindo o que causou o erro de compilação.
- Veja a linha no arquivo indicado pela mensagem de erro de compilação.
- Identifique qual símbolo está falando da mensagem de erro.
- 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. Finalmente, você decide a correção que precisa fazer no seu código-fonte para fazer o que deseja.
Observe que nem todas as "correções" estã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 eu "consertar" isso:
- Eu poderia mudar o interior
for
para for (int j = 1; j < 10; j++)
- provavelmente correto.
- Eu poderia adicionar uma declaração
j
antes do for
loop interno ou externo for
- possivelmente correto.
- Eu poderia mudar
j
para i
no for
loop 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 correta.
4. Causas obscuras
Aqui estão alguns casos em que o "Não é possível encontrar o símbolo" é aparentemente inexplicável ... até você olhar mais de perto.
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, deixou de fora 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.
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 seu rabo procurando um erro ilusório que é realmente causado por não recompilar o código corretamente, e coisas do tipo ...
Um problema de construção anterior : é possível que uma construção anterior tenha falhado de uma maneira que forneceu um arquivo JAR com classes ausentes. Essa falha normalmente seria notada se você estivesse usando uma ferramenta de construção. No entanto, se você está recebendo arquivos JAR de outra pessoa, você é dependente de lhes construir corretamente, e percebendo erros. Se você suspeitar disso, use tar -tvf
para listar o conteúdo do arquivo JAR suspeito.
Problemas com o IDE : as pessoas relataram casos em que o IDE fica confuso e o compilador no IDE não consegue encontrar uma classe que existe ... 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 corrigir isso.
Isso pode ser um bug do IDE. Por exemplo, @Joel Costigliola descreve um cenário em que o Eclipse não manipula uma árvore de "teste" do Maven corretamente: consulte esta resposta .
Problemas com o Android : quando você estiver programando para o Android e tiver erros relacionados a "Não é possível encontrar o símbolo" R
, lembre-se de que os R
símbolos são definidos pelo context.xml
arquivo. Verifique se o seu context.xml
arquivo está correto e no lugar correto, e se o R
arquivo 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.
É provável que outros erros de símbolo no Android sejam causados por razões de menção anterior; por exemplo, dependências ausentes ou incorretas, nomes de pacotes incorretos, métodos ou campos que não existem em uma versão específica da API, erros de ortografia / digitação e assim por diante.
Redefinindo classes de sistema : eu 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 String
e que sua versão da classe não definia um substring
método.
Lição: não defina suas próprias classes com os mesmos nomes que as classes comuns da biblioteca!
Homoglyphs: Se você usar a codificação UTF-8 para seus arquivos de origem, é possível ter identificadores com a mesma aparência , mas são de fato diferentes porque contêm homoglyphs. 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 \uxxxx
escapes de 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 flui para cima, uma prancha é mais forte de lado e você não pode empurrar uma corda .
println
,System.out.println
se colocado no nível da classe no compilador padrão nos daria<identifier> expected
( demo ), mas no IntelliJ veremosCannot resolve symbol 'println'
( demo ).Você também receberá esse erro se esquecer de
new
:versus
porque a chamada sem a
new
palavra - chave tentará procurar um método (local) chamadoString
sem argumentos - e essa assinatura do método provavelmente não está definida.fonte
Mais um exemplo de 'Variável está fora do escopo'
Como já vi esse tipo de perguntas algumas vezes, talvez mais um exemplo do que é ilegal, mesmo que possa parecer bom.
Considere este código:
Esse código é inválido. Como nenhuma das variáveis nomeadas
message
é visível fora do respectivo escopo - quais seriam os colchetes{}
nesse caso.Você pode dizer: "Mas uma variável chamada mensagem é definida de qualquer maneira - portanto, a mensagem é definida após o
if
".Mas você estaria errado.
O Java não possui operadores
free()
oudelete
, portanto, ele deve confiar no 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 de bom. Eu vi esse tipo de erro depois de "otimizar" o código assim:
"Oh, há código duplicado, vamos puxar essa linha comum" -> e aí está.
A maneira mais comum de lidar com esse tipo de problema de escopo seria atribuir previamente os valores else aos nomes de variáveis no escopo externo e, em seguida, reatribuir se:
fonte
final
.Uma maneira de obter esse erro no Eclipse:
A
emsrc/test/java
.B
emsrc/main/java
que a classe usosA
.Resultado: o Eclipse compilará o código, mas o maven fornecerá "Não é possível encontrar o símbolo".
Causa subjacente: O Eclipse está usando um caminho de construção combinado para as árvores principal e de teste. Infelizmente, ele não suporta o uso de caminhos de construção diferentes para diferentes partes de um projeto Eclipse, que é o que o Maven exige.
Solução:
fonte
"Não é possível encontrar" significa que, o compilador que não consegue encontrar a variável, método, classe, etc. apropriados ... se você recebeu a massagem com erro, antes de mais nada, deseja encontrar a linha de código onde recebe a massagem com erro ... E então você 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 requerer mais tarde ... Considere o seguinte exemplo.
Vou criar uma aula de demonstração e imprimir um nome ...
Agora veja o resultado ..
Esse erro diz: "o nome da variável não pode encontrar". A definição e a inicialização do valor da variável 'name' podem ser abolidas nesse erro. Na verdade, dessa forma,
Agora veja a nova saída ...
Ok Resolvido com êxito esse erro .. Ao mesmo tempo, se você pudesse obter algo "não é possível encontrar o método" ou "não é possível encontrar a classe", primeiro defina uma classe ou método e depois use-o ..
fonte
Se você estiver recebendo esse erro na compilação em outro lugar, enquanto o IDE diz que tudo está perfeitamente bem, verifique se você está usando as mesmas versões do Java nos dois lugares.
Por exemplo, Java 7 e Java 8 têm APIs diferentes, portanto, chamar uma API inexistente em uma versão Java mais antiga causaria esse erro.
fonte
Eu também estava recebendo esse erro. (pelo qual pesquisei no Google 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. Eu estava recebendo o seguinte erro:
Solução: resolvi isso criando primeiro o projeto em que o método está definido e depois o projeto de onde o método estava sendo chamado.
fonte
Se o caminho de construção do eclipse Java estiver mapeado para 7, 8 e nas propriedades do Projeto pom.xml Maven, java.version será mencionada na versão Java superior (9,10,11, etc.) que 7,8, você precisará atualizar no pom. arquivo xml.
No Eclipse, se o Java estiver mapeado para o Java versão 11 e no pom.xml, ele será mapeado para o Java versão 8. Atualize o suporte do Eclipse para o Java 11 seguindo as etapas abaixo na Ajuda do eclipse IDE -> Instalar novo software ->
Cole o link a seguir http://download.eclipse.org/eclipse/updates/4.9-P-builds em trabalho com
ou
Adicionar (a janela pop-up será aberta) ->
Name:
Suporte ao Java 11Location:
http://download.eclipse.org/eclipse/updates/4.9-P-buildsatualize a versão Java nas propriedades do Maven do arquivo pom.xml, conforme abaixo
Por fim, clique com o botão direito do mouse no projeto Debug como -> Maven clean, Maven build steps
fonte
RESOLVIDO
Selecione Build -> Rebuild Project irá resolvê-lo
fonte
Pode haver vários cenários, como as pessoas mencionaram acima. Algumas coisas que me ajudaram a resolver isso.
Se você estiver usando o IntelliJ
File -> 'Invalidate Caches/Restart'
OU
A classe que está sendo referenciada estava em outro projeto e essa dependência não foi adicionada ao arquivo de construção Gradle do meu projeto. Então eu adicionei a dependência usando
compile project(':anotherProject')
e funcionou. HTH!
fonte
você compilou seu código usando o maven compile e depois usou o maven test para executá-lo funcionou bem. Agora, se você alterou algo no seu código e, em seguida, sem compilá-lo, você receberá esse erro.
Solução: Compile novamente e execute o teste. Para mim, funcionou dessa maneira.
fonte
No meu caso - tive que executar as operações abaixo:
context.xml
arquivo desrc/java/package
para oresource
diretório (IntelliJ IDE)target
Diretório limpo .fonte
Para obter dicas, olhe mais de perto o nome do nome da classe que gera 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 da versão java, digamos jdk7 vs 8. Verifique seu% JAVA_HOME%
fonte