0. Gibt es einen Unterschied zwischen den beiden Fehlern?
Nicht wirklich. "Symbol kann nicht gefunden werden" und "Symbol kann nicht aufgelöst werden" bedeuten dasselbe. Einige Java-Compiler verwenden eine Phrase, andere die andere.
1. Was bedeutet ein Fehler "Symbol kann nicht gefunden werden"?
Erstens ist es ein Kompilierungsfehler 1 . Dies bedeutet, dass entweder ein Problem in Ihrem Java-Quellcode vorliegt oder dass bei der Kompilierung ein Problem vorliegt .
Ihr Java-Quellcode besteht aus folgenden Elementen:
- Stichwort: wie
true
, false
, class
, while
, und so weiter.
- Literale: wie
42
und 'X'
und "Hi mum!"
.
- Betreiber und andere nicht-alphanumerische Token: wie
+
, =
, {
, und so weiter.
- Identifiers: wie
Reader
, i
, toString
, processEquibalancedElephants
, und so weiter.
- Kommentare und Leerzeichen.
Ein Fehler "Symbol kann nicht gefunden werden" betrifft die Bezeichner. Wenn Ihr Code kompiliert wird, muss der Compiler herausfinden, was jeder einzelne Bezeichner in Ihrem Code bedeutet.
Ein Fehler "Symbol kann nicht gefunden werden" bedeutet, dass der Compiler dies nicht tun kann. Ihr Code scheint sich auf etwas zu beziehen, das der Compiler nicht versteht.
2. Was kann den Fehler "Symbol kann nicht gefunden werden" verursachen?
Als erste Bestellung gibt es nur eine Ursache. Der Compiler sah in all den Orten , an denen die Kennung sollte festgelegt werden, und es könnte die Definition nicht finden. Dies kann durch eine Reihe von Dingen verursacht werden. Die häufigsten sind wie folgt:
- Für Bezeichner im Allgemeinen:
- Vielleicht haben Sie den Namen falsch geschrieben; dh
StringBiulder
statt StringBuilder
. Java kann und wird nicht versuchen, falsche Rechtschreib- oder Tippfehler zu kompensieren.
- Vielleicht haben Sie den Fall falsch verstanden; dh
stringBuilder
statt StringBuilder
. Bei allen Java-Bezeichnern wird zwischen Groß- und Kleinschreibung unterschieden.
- Vielleicht haben Sie Unterstriche unangemessen verwendet; dh
mystring
und my_string
sind anders. (Wenn Sie sich an die Java-Regeln halten, sind Sie weitgehend vor diesem Fehler geschützt ...)
- Vielleicht versuchen Sie etwas zu verwenden, das als "woanders" deklariert wurde; dh in einem anderen Kontext als dem, in dem Sie den Compiler implizit angewiesen haben, nachzuschauen. (Eine andere Klasse? Ein anderer Bereich? Ein anderes Paket? Eine andere Codebasis?)
- Für Bezeichner, die sich auf Variablen beziehen sollten:
- Vielleicht haben Sie vergessen, die Variable zu deklarieren.
- Möglicherweise ist die Variablendeklaration an dem Punkt, an dem Sie versucht haben, sie zu verwenden, außerhalb des Gültigkeitsbereichs. (Siehe Beispiel unten)
Für Bezeichner, die Methoden- oder Feldnamen sein sollten:
Für Bezeichner, die Klassennamen sein sollten:
In Fällen, in denen Typ oder Instanz nicht das Mitglied zu haben scheint, das Sie erwartet haben:
- Möglicherweise haben Sie eine verschachtelte Klasse oder einen generischen Parameter deklariert, der den Typ überschattet, den Sie verwenden wollten.
- Möglicherweise schattieren Sie eine statische oder Instanzvariable.
- Vielleicht haben Sie den falschen Typ importiert. zB aufgrund von IDE-Vervollständigung oder automatischer Korrektur.
- Möglicherweise verwenden Sie die falsche Version einer API (kompilieren dagegen).
- Vielleicht haben Sie vergessen, Ihr Objekt in eine geeignete Unterklasse umzuwandeln.
Das Problem ist oft eine Kombination der oben genannten. Zum Beispiel haben Sie vielleicht "Stern" importiert java.io.*
und dann versucht, die Files
Klasse zu verwenden ... die in java.nio
nicht ist java.io
. Oder vielleicht wolltest du schreiben File
... das ist eine Klasse in java.io
.
Hier ist ein Beispiel dafür, wie ein falscher Gültigkeitsbereich von Variablen zu einem Fehler "Symbol kann nicht gefunden werden" führen kann:
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
Dies führt zu einem Fehler "Symbol kann nicht gefunden werden" i
in der if
Anweisung. Obwohl wir vorher erklärt i
, ist diese Erklärung nur in Rahmen für die for
Erklärung und seinen Körper. Der Verweis auf i
in der if
Erklärung kann diese Erklärung von nicht seheni
. Es ist außerhalb des Geltungsbereichs .
(Eine geeignete Korrektur könnte darin bestehen, die if
Anweisung innerhalb der Schleife zu verschieben oder i
vor dem Start der Schleife zu deklarieren .)
Hier ist ein Beispiel, das Verwirrung stiftet, wenn ein Tippfehler zu einem scheinbar unerklärlichen Fehler "Symbol kann nicht gefunden werden" führt:
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
Dies gibt Ihnen einen Kompilierungsfehler im println
Aufruf, der besagt, dass i
nicht gefunden werden kann. Aber (ich höre dich sagen) ich habe es erklärt!
Das Problem ist das hinterhältige Semikolon ( ;
) vor dem {
. Die Java-Sprachsyntax definiert ein Semikolon in diesem Kontext als leere Anweisung . Die leere Anweisung wird dann zum Hauptteil der for
Schleife. Dieser Code bedeutet also tatsächlich Folgendes:
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
Der { ... }
Block ist NICHT der Hauptteil der for
Schleife, und daher ist die vorherige Deklaration von i
in der for
Anweisung im Block außerhalb des Gültigkeitsbereichs .
Hier ist ein weiteres Beispiel für den Fehler "Symbol kann nicht gefunden werden", der durch einen Tippfehler verursacht wird.
int tmp = ...
int res = tmp(a + b);
Trotz der vorherigen Erklärung ist das tmp
im tmp(...)
Ausdruck fehlerhaft. Der Compiler sucht nach einer Methode namens tmp
und findet keine. Das zuvor deklarierte tmp
befindet sich im Namespace für Variablen, nicht im Namespace für Methoden.
In dem Beispiel, auf das ich gestoßen bin, hatte der Programmierer tatsächlich einen Operator ausgelassen. Was er schreiben wollte, war Folgendes:
int res = tmp * (a + b);
Es gibt einen weiteren Grund, warum der Compiler möglicherweise kein Symbol findet, wenn Sie über die Befehlszeile kompilieren. Möglicherweise haben Sie einfach vergessen, eine andere Klasse zu kompilieren oder neu zu kompilieren. Zum Beispiel, wenn Sie Klassen haben Foo
und Bar
wo Foo
verwendet wird Bar
. Wenn Sie noch nie kompiliert haben Bar
und ausgeführt werden javac Foo.java
, können Sie feststellen, dass der Compiler das Symbol nicht finden kann Bar
. Die einfache Antwort ist zu kompilieren Foo
und Bar
zusammen; zB javac Foo.java Bar.java
oder javac *.java
. Oder verwenden Sie besser noch ein Java-Build-Tool. zB Ant, Maven, Gradle und so weiter.
Es gibt noch einige andere dunkelere Ursachen ... auf die ich weiter unten eingehen werde.
3. Wie behebe ich diese Fehler?
Im Allgemeinen beginnen Sie herauszufinden, was verursacht den Kompilierung - Fehler.
- Sehen Sie sich die Zeile in der Datei an, die in der Kompilierungsfehlermeldung angegeben ist.
- Identifizieren Sie, um welches Symbol es sich bei der Fehlermeldung handelt.
- Finden Sie heraus, warum der Compiler sagt, dass er das Symbol nicht finden kann. siehe oben!
Dann überlegen Sie , was Ihr Code sagen soll. Dann erarbeiten Sie schließlich, welche Korrektur Sie an Ihrem Quellcode vornehmen müssen, um das zu tun, was Sie wollen.
Beachten Sie, dass nicht jede "Korrektur" korrekt ist. Bedenken Sie:
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
Angenommen, der Compiler sagt "Symbol kann nicht gefunden werden" für j
. Es gibt viele Möglichkeiten, wie ich das "beheben" kann:
- Ich konnte die innere ändern
for
zu for (int j = 1; j < 10; j++)
- wahrscheinlich richtig.
- Ich könnte eine Deklaration für
j
vor der inneren for
oder der äußeren for
Schleife hinzufügen - möglicherweise richtig.
- Ich könnte sich ändern ,
j
um i
in der inneren for
Schleife - wahrscheinlich falsch!
- und so weiter.
Der Punkt ist, dass Sie verstehen müssen , was Ihr Code versucht, um die richtige Lösung zu finden.
4. Dunkle Ursachen
Hier sind einige Fälle, in denen das Symbol "Symbol nicht gefunden" scheinbar unerklärlich ist ... bis Sie genauer hinschauen.
Falsche Abhängigkeiten : Wenn Sie eine IDE oder ein Build-Tool verwenden, das den Build-Pfad und die Projektabhängigkeiten verwaltet, haben Sie möglicherweise einen Fehler mit den Abhängigkeiten gemacht. zB eine Abhängigkeit ausgelassen oder die falsche Version ausgewählt. Wenn Sie ein Build-Tool (Ant, Maven, Gradle usw.) verwenden, überprüfen Sie die Build-Datei des Projekts. Wenn Sie eine IDE verwenden, überprüfen Sie die Konfiguration des Erstellungspfads des Projekts.
Sie kompilieren nicht neu : Es kommt manchmal vor, dass neue Java-Programmierer die Funktionsweise der Java-Toolkette nicht verstehen oder keinen wiederholbaren "Erstellungsprozess" implementiert haben. zB mit einer IDE, Ant, Maven, Gradle und so weiter. In einer solchen Situation kann der Programmierer seinen Schwanz verfolgen und nach einem illusorischen Fehler suchen, der tatsächlich dadurch verursacht wird, dass der Code nicht richtig neu kompiliert wird, und dergleichen ...
Ein früheres Build-Problem : Möglicherweise ist ein früherer Build auf eine Weise fehlgeschlagen, die eine JAR-Datei mit fehlenden Klassen ergab. Ein solcher Fehler wird normalerweise bemerkt, wenn Sie ein Build-Tool verwenden. Wenn Sie jedoch JAR-Dateien von einer anderen Person erhalten, sind Sie darauf angewiesen, dass diese ordnungsgemäß erstellt werden und Fehler feststellen. Wenn Sie dies vermuten, verwenden Sie, um tar -tvf
den Inhalt der verdächtigen JAR-Datei aufzulisten.
IDE-Probleme : Personen haben Fälle gemeldet, in denen ihre IDE verwirrt ist und der Compiler in der IDE keine vorhandene Klasse finden kann ... oder die umgekehrte Situation.
Dies kann passieren, wenn die IDE mit der falschen JDK-Version konfiguriert wurde.
Dies kann passieren, wenn die Caches der IDE nicht mehr mit dem Dateisystem synchronisiert sind. Es gibt IDE-spezifische Möglichkeiten, dies zu beheben.
Dies könnte ein IDE-Fehler sein. Zum Beispiel beschreibt @Joel Costigliola ein Szenario, in dem Eclipse einen Maven-Testbaum nicht richtig behandelt: siehe diese Antwort .
Android-Probleme : Wenn Sie für Android programmieren und Fehler im Zusammenhang mit "Symbol kann nicht gefunden werden" haben R
, beachten Sie, dass die R
Symbole in der context.xml
Datei definiert sind . Überprüfen Sie, ob Ihre context.xml
Datei korrekt und an der richtigen Stelle ist und ob die entsprechende R
Klassendatei generiert / kompiliert wurde. Beachten Sie, dass bei den Java-Symbolen zwischen Groß- und Kleinschreibung unterschieden wird, sodass bei den entsprechenden XML-IDs auch zwischen Groß- und Kleinschreibung unterschieden wird.
Andere Symbolfehler unter Android sind wahrscheinlich auf zuvor erwähnte Gründe zurückzuführen. zB fehlende oder falsche Abhängigkeiten, falsche Paketnamen, Methoden oder Felder, die in einer bestimmten API-Version nicht vorhanden sind, Rechtschreib- / Tippfehler usw.
Systemklassen neu definieren : Ich habe Fälle gesehen, in denen sich der Compiler beschwert, dass dies substring
ein unbekanntes Symbol ist
String s = ...
String s1 = s.substring(1);
Es stellte sich heraus, dass der Programmierer eine eigene Version von erstellt hatte String
und dass seine Version der Klasse keine substring
Methoden definierte .
Lektion: Definieren Sie keine eigenen Klassen mit denselben Namen wie allgemeine Bibliotheksklassen!
Homoglyphen: Wenn Sie für Ihre Quelldateien die UTF-8-Codierung verwenden, können Bezeichner verwendet werden, die gleich aussehen , sich jedoch unterscheiden, da sie Homoglyphen enthalten. Weitere Informationen finden Sie auf dieser Seite .
Sie können dies vermeiden, indem Sie sich auf ASCII oder Latin-1 als Quelldatei-Codierung beschränken und Java- \uxxxx
Escapezeichen für andere Zeichen verwenden.
1 - Wenn, vielleicht, Sie haben sehen dies in einer Runtime - Ausnahme oder eine Fehlermeldung, dann haben Sie entweder Ihre IDE Laufcode mit Kompilierungsfehlern konfigurieren oder Ihre Anwendung generiert und Kompilieren von Code .. zur Laufzeit.
2 - Die drei Grundprinzipien des Bauingenieurwesens: Wasser fließt nicht bergauf, eine Planke ist auf der Seite stärker und man kann nicht an einer Schnur drücken .
println
in,System.out.println
wenn auf Klassenebene unter Standard-Compiler platziert würde uns<identifier> expected
( Demo ) geben, aber in IntelliJ werden wir sehenCannot resolve symbol 'println'
( Demo ).Sie erhalten diesen Fehler auch, wenn Sie Folgendes vergessen
new
:gegen
weil der Aufruf ohne das
new
Schlüsselwort versucht, nach einer (lokalen) Methode zu suchen, dieString
ohne Argumente aufgerufen wird - und diese Methodensignatur wahrscheinlich nicht definiert ist.quelle
Ein weiteres Beispiel für "Variable ist außerhalb des Gültigkeitsbereichs"
Wie ich diese Art von Fragen schon einige Male gesehen habe, vielleicht ein weiteres Beispiel dafür, was illegal ist, auch wenn es sich in Ordnung anfühlt .
Betrachten Sie diesen Code:
Das ist ungültiger Code. Weil keine der genannten Variablen
message
außerhalb ihres jeweiligen Bereichs sichtbar ist -{}
in diesem Fall wären dies die umgebenden Klammern .Man könnte sagen: „Aber eine Variable mit dem Namen Nachricht wird so oder so definiert - so Meldung wird nach der definierten
if
“.Aber du liegst falsch.
Java hat keine
free()
oderdelete
Operatoren, daher muss es sich auf die Verfolgung des Variablenbereichs verlassen, um herauszufinden, wann Variablen nicht mehr verwendet werden (zusammen mit Verweisen auf diese Variablen der Ursache).Es ist besonders schlimm, wenn Sie dachten, Sie hätten etwas Gutes getan. Ich habe diese Art von Fehler gesehen, nachdem ich Code wie folgt "optimiert" habe:
"Oh, es gibt doppelten Code, lass uns diese gemeinsame Linie herausziehen" -> und da ist es.
Die gebräuchlichste Methode, um mit dieser Art von Scope-Problemen umzugehen, besteht darin, die else-Werte den Variablennamen im externen Scope vorab zuzuweisen und sie dann neu zuzuweisen, wenn:
quelle
final
Variablendeklaration.Eine Möglichkeit, diesen Fehler in Eclipse zu erhalten:
A
insrc/test/java
.B
insrc/main/java
dieser AnwendungsklasseA
.Ergebnis: Eclipse kompiliert den Code, aber Maven gibt "Symbol kann nicht gefunden werden".
Grundursache: Eclipse verwendet einen kombinierten Erstellungspfad für die Haupt- und Testbäume. Leider wird die Verwendung unterschiedlicher Erstellungspfade für verschiedene Teile eines Eclipse-Projekts nicht unterstützt, was Maven benötigt.
Lösung:
quelle
"Kann nicht finden" bedeutet, dass Compiler, der keine geeignete Variable, Methode, Klasse usw. finden kann. Wenn Sie diese Fehlermassage erhalten haben, möchten Sie zunächst eine Codezeile finden, in der Sie eine Fehlermassage erhalten. Und dann werden Sie Sie können feststellen, welche Variable, Methode oder Klasse vor der Verwendung nicht definiert wurde. Nach der Bestätigung initialisieren Sie, dass die Variable, Methode oder Klasse für spätere Anforderungen verwendet werden kann. Betrachten Sie das folgende Beispiel.
Ich werde eine Demo-Klasse erstellen und einen Namen drucken ...
Schauen Sie sich jetzt das Ergebnis an.
Dieser Fehler besagt, dass "Variablenname nicht gefunden werden kann". Durch Definieren und Initialisieren des Werts für die Variable "Name" kann dieser Fehler behoben werden.
Schauen Sie sich jetzt die neue Ausgabe an ...
Ok Dieser Fehler wurde erfolgreich behoben. Wenn Sie gleichzeitig die Meldung "Methode kann nicht gefunden werden" oder "Klasse kann nicht gefunden werden" erhalten, definieren Sie zunächst eine Klasse oder Methode und verwenden Sie diese anschließend.
quelle
Wenn Sie diesen Fehler im Build an einer anderen Stelle erhalten, während Ihre IDE angibt, dass alles in Ordnung ist, überprüfen Sie, ob Sie an beiden Stellen dieselben Java-Versionen verwenden.
Beispielsweise verfügen Java 7 und Java 8 über unterschiedliche APIs. Das Aufrufen einer nicht vorhandenen API in einer älteren Java-Version würde diesen Fehler verursachen.
quelle
Auch ich habe diesen Fehler bekommen. (wofür ich gegoogelt habe und auf diese Seite verwiesen wurde)
Problem: Ich habe eine in der Klasse eines Projekts A definierte statische Methode aus einer in einem anderen Projekt B definierten Klasse aufgerufen. Ich habe den folgenden Fehler erhalten:
Lösung: Ich habe dieses Problem behoben, indem ich zuerst das Projekt erstellt habe, in dem die Methode definiert ist, und dann das Projekt, von dem aus die Methode aufgerufen wurde.
quelle
Wenn der Eclipse-Java-Erstellungspfad 7, 8 zugeordnet ist und in Project pom.xml Maven-Eigenschaften java.version eine höhere Java-Version (9,10,11 usw.) als 7,8 erwähnt wird, müssen Sie in pom aktualisieren. XML-Datei.
Wenn in Eclipse Java Java Version 11 und in pom.xml Java Version 8 zugeordnet ist, aktualisieren Sie die Eclipse-Unterstützung auf Java 11, indem Sie die folgenden Schritte in der Eclipse IDE-Hilfe ausführen -> Neue Software installieren ->
Fügen Sie den folgenden Link ein: http://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With
oder
Hinzufügen (Popup-Fenster wird geöffnet) ->
Name:
Java 11 unterstütztLocation:
http://download.eclipse.org/eclipse/updates/4.9-P-buildsAktualisieren Sie dann die Java-Version in den Maven-Eigenschaften der Datei pom.xml wie folgt
Klicken Sie abschließend mit der rechten Maustaste auf Projekt Debuggen als -> Maven bereinigen, Maven Build-Schritte
quelle
Gelöst
Wählen Sie Erstellen -> Projekt neu erstellen , um das Problem zu lösen
quelle
Es kann verschiedene Szenarien geben, wie oben erwähnt. Ein paar Dinge, die mir geholfen haben, dieses Problem zu lösen.
Wenn Sie IntelliJ verwenden
File -> 'Invalidate Caches/Restart'
ODER
Die Klasse, auf die verwiesen wird, befand sich in einem anderen Projekt, und diese Abhängigkeit wurde nicht zur Gradle-Builddatei meines Projekts hinzugefügt. Also habe ich die Abhängigkeit mit hinzugefügt
compile project(':anotherProject')
und es hat funktioniert. HTH!
quelle
Sie haben Ihren Code mit maven compile kompiliert und dann mit maven test ausgeführt. Wenn Sie nun etwas in Ihrem Code geändert haben und es dann ohne Kompilieren ausführen, wird dieser Fehler angezeigt.
Lösung: Kompilieren Sie es erneut und führen Sie dann den Test aus. Bei mir hat es so funktioniert.
quelle
In meinem Fall musste ich folgende Operationen ausführen:
context.xml
Datei aus ,src/java/package
um dasresource
Verzeichnis (IntelliJ IDE)target
Verzeichnis bereinigen .quelle
Hinweise finden Sie unter dem Namen des Klassennamens, der einen Fehler auslöst, und der Zeilennummer. Beispiel: Kompilierungsfehler [FEHLER] \ Anwendungen \ xxxxx.java: [44,30] Fehler: Symbol kann nicht gefunden werden
Eine andere Ursache ist die nicht unterstützte Methode für die Java-Version, z. B. jdk7 vs 8. Überprüfen Sie Ihre% JAVA_HOME%
quelle