回答:
あんまり。「シンボルが見つかりません」と「シンボルを解決できません」は同じ意味です。一部のJavaコンパイラは1つの句を使用し、一部は他の句を使用します。
まず、これはコンパイルエラーです1。それは意味のいずれかの Javaソースコードに問題がある、またはあなたがそれをコンパイルしているというやり方に問題があります。
Javaソースコードは次の要素で構成されています。
true
、false
、class
、while
、など。42
および'X'
およびのような"Hi mum!"
。+
、=
、{
、など。Reader
、i
、toString
、processEquibalancedElephants
、など。「シンボルが見つかりません」エラーは、識別子に関するものです。コードがコンパイルされると、コンパイラーはコード内のすべての識別子の意味を理解する必要があります。
「シンボルが見つかりません」エラーは、コンパイラがこれを実行できないことを意味します。あなたのコードはコンパイラが理解できない何かを参照しているようです。
最初の注文として、原因は1つだけです。コンパイラは、識別子を定義する必要があるすべての場所を調べましたが、定義を見つけることができませんでした。これにはいくつかの原因が考えられます。一般的なものは次のとおりです。
StringBiulder
代わりにStringBuilder
。Javaは、スペルミスや入力ミスを補うことはできません。stringBuilder
代わりにStringBuilder
。すべてのJava識別子は大文字と小文字を区別します。mystring
、とmy_string
は異なります。(Javaスタイルのルールに固執すれば、この間違いからほぼ保護されます...)メソッド名またはフィールド名であるべき識別子の場合:
"someString".push()
2。"someString".length
またはsomeArray.length()
。おそらく、配列要素ではなく配列を誤って操作している可能性があります。例えば
String strings[] = ...
if (strings.charAt(3)) { ... }
// maybe that should be 'strings[0].charAt(3)'
クラス名であるべき識別子の場合:
多分あなたはのnew
ように忘れました:
String s = String(); // should be 'new String()'
タイプまたはインスタンスに、予期したメンバーが含まれていないと思われる場合:
多くの場合、問題は上記の組み合わせです。たとえば、「スター」をインポートjava.io.*
してから、Files
クラス…を使用しようとした可能性がjava.nio
ありjava.io
ます。あるいは、あなたが書くつもりだったかもしれませんFile
...これはのクラスですjava.io
。
変数のスコープが正しくないと、「シンボルが見つかりません」というエラーが発生する例を次に示します。
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
これi
により、if
ステートメントで「シンボルが見つかりません」エラーが発生します。以前に宣言しましたがi
、その宣言はステートメントとその本文のスコープ内にのみありますfor
。ステートメントi
内のへの参照では、そのの宣言を見ることができません。それは適用範囲外。if
i
(ここでの適切な修正は、if
ステートメントをループ内に移動するか、ループi
の開始前に宣言することです。)
誤字が原因で一見不可解な「シンボルが見つかりません」というエラーが発生するという困惑を引き起こす例を次に示します。
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
これにより、見つからないprintln
というコールのコンパイルエラーが発生しますi
。しかし、(私はあなたが言うのを聞きます)私はそれを宣言しました!
問題は、;
前の卑劣なセミコロン(){
です。Java言語の構文では、そのコンテキストでセミコロンを空のステートメントとして定義しています。次に、空のステートメントがfor
ループの本体になります。したがって、そのコードは実際にこれを意味します:
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
{ ... }
ブロックは、本体ではありませんfor
ループ、そのための前の宣言i
でfor
ステートメントがあるスコープ外ブロックで。
これは、タイプミスが原因の「シンボルが見つかりません」エラーの別の例です。
int tmp = ...
int res = tmp(a + b);
前の宣言にもかかわらず、式のtmp
in tmp(...)
は誤りです。コンパイラはというメソッドを探しますが、tmp
見つかりません。以前に宣言されたのtmp
は、メソッドの名前空間ではなく、変数の名前空間です。
私が遭遇した例では、プログラマーは実際にはオペレーターを省いていた。彼が書くつもりだったのはこれです:
int res = tmp * (a + b);
コマンドラインからコンパイルしている場合、コンパイラがシンボルを見つけられない場合があるもう1つの理由があります。他のクラスをコンパイルまたは再コンパイルするのを忘れただけかもしれません。たとえば、クラスがFoo
あり、Bar
がをFoo
使用している場合Bar
。コンパイルしたことがなくBar
、実行javac Foo.java
した場合、コンパイラがシンボルを見つけられない可能性がありますBar
。簡単な答えは、コンパイルFoo
してBar
一緒にすることです。たとえばjavac Foo.java Bar.java
またはjavac *.java
。または、Javaビルドツールを使用することをお勧めします。例:Ant、Maven、Gradleなど。
他にも不明瞭な原因がいくつかあります...これについては以下で扱います。
一般的に言えば、コンパイルエラーの原因を突き止めることから始めます。
次に、あなたが考えるあなたのコードが言ってことになっているものについて。次に、最終的に、ソースコードに必要な修正を加えて、必要なことを行います。
すべての「修正」が正しいわけではないことに注意してください。このことを考慮:
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
コンパイラがの「シンボルが見つかりません」と言ったとしますj
。それを「修正」できる方法はたくさんあります。
for
を変更することができましたfor (int j = 1; j < 10; j++)
-おそらく正しいです。j
前に宣言を追加できます-おそらく正しいです。for
for
j
にi
、内側にfor
ループ-おそらく間違っています!ポイントは、正しい修正を見つけるために、コードが何をしようとしているのかを理解する必要があるということです。
ここでは、「シンボルが見つかりません」が不可解なように見えるいくつかのケースを示します...よく見るまで。
不適切な依存関係:ビルドパスとプロジェクトの依存関係を管理するIDEまたはビルドツールを使用している場合は、依存関係に誤りがある可能性があります。たとえば、依存関係を省略したり、間違ったバージョンを選択した。ビルドツール(Ant、Maven、Gradleなど)を使用している場合は、プロジェクトのビルドファイルを確認してください。IDEを使用している場合は、プロジェクトのビルドパス構成を確認してください。
再コンパイルしていない:新しいJavaプログラマーがJavaツールチェーンの動作を理解していないか、繰り返し可能な「ビルドプロセス」を実装していない場合があります。たとえば、IDE、Ant、Maven、Gradleなどを使用します。このような状況では、プログラマーはコードを適切に再コンパイルしなかったことなどによって実際に引き起こされている幻想的なエラーを探して尾を追いかけてしまう可能性があります...
以前のビルドの問題:クラスが欠落しているJARファイルを提供するように、以前のビルドが失敗した可能性があります。このような障害は、ビルドツールを使用している場合に通常発生します。ただし、他の人からJARファイルを取得している場合は、それらが適切にビルドされ、エラーが発生していることに依存しています。これが疑われる場合は、を使用tar -tvf
して、疑わしいJARファイルの内容をリストします。
IDEの問題:IDEが混乱し、IDEのコンパイラーが存在するクラスを見つけられない、またはその逆の状況が報告されています。
これは、IDEが間違ったJDKバージョンで構成されている場合に発生する可能性があります。
これは、IDEのキャッシュがファイルシステムと同期しなくなった場合に発生する可能性があります。これを修正するIDE固有の方法があります。
これはIDEのバグである可能性があります。たとえば、@ Joel Costigliolaは、EclipseがMavenの「テスト」ツリーを正しく処理しないシナリオについて説明しています。この回答を参照してください。
Androidの問題:Android向けにプログラミングしていてR
、に関連する「シンボルが見つかりません」というエラーがある場合、R
シンボルはcontext.xml
ファイルによって定義されていることに注意してください。context.xml
ファイルが正しく、正しい場所にあること、および対応するR
クラスファイルが生成/コンパイルされていることを確認してください。Javaシンボルでは大文字と小文字が区別されるため、対応するXML IDでも大文字と小文字が区別されることに注意してください。
Androidでの他のシンボルエラーは、前述の理由が原因である可能性があります。たとえば、欠落または不適切な依存関係、不適切なパッケージ名、特定のAPIバージョンに存在しないメソッドまたはフィールド、スペル/タイプ入力エラーなど。
システムクラスの再定義:コンパイラsubstring
が次のような未知のシンボルであると文句を言う場合を見てきました。
String s = ...
String s1 = s.substring(1);
プログラマーがの独自のバージョンを作成しString
、クラスの彼のバージョンはsubstring
メソッドを定義していないことがわかりました。
レッスン:一般的なライブラリクラスと同じ名前で独自のクラスを定義しないでください。
ホモグリフ: ソースファイルにUTF-8エンコーディングを使用している場合、同じように見える識別子を使用できますが、ホモグリフが含まれているため実際には異なります。詳細については、このページを参照してください。
これを回避するには、ソースファイルエンコーディングをASCIIまたはLatin-1に制限し\uxxxx
、他の文字にJava エスケープを使用します。
1 -もし、恐らく、あなたはない、あなたはコンパイルエラーでコードを実行するために、あなたのIDEを設定している、またはアプリケーションが生成し、実行時に...コードをコンパイルされるか、実行時例外やエラーメッセージにこれを参照してください。
2-土木工学の3つの基本原則:水は上り坂を流れず、厚板はその側が強く、紐を押すことはできません。
「変数は範囲外です」のもう1つの例
この種の質問をすでに何度か見てきたので、たとえ大丈夫だと思っていても違法なもののもう1つの例を示します。
このコードを考えてみましょう:
if(somethingIsTrue()) {
String message = "Everything is fine";
} else {
String message = "We have an error";
}
System.out.println(message);
これは無効なコードです。というのも、指定された変数message
はどちらも、それぞれのスコープの外には表示されません{}
。
「しかし、messageという名前の変数はどちらかの方法で定義されているため、message はif
"の後に定義されます。
しかし、あなたは間違っているでしょう。
Javaにはfree()
or delete
演算子がないため、変数が使用されなくなった時期を(これらの原因の変数への参照と共に)追跡するために変数スコープを追跡する必要があります。
何か良いことをしたと思った場合は特に悪いことです。次のようなコードを「最適化」した後、この種のエラーが発生しました。
if(somethingIsTrue()) {
String message = "Everything is fine";
System.out.println(message);
} else {
String message = "We have an error";
System.out.println(message);
}
「ああ、重複したコードがあるので、その共通の行を引き出しましょう」->そして、それです。
この種のスコープの問題に対処する最も一般的な方法は、else-valuesを外部スコープの変数名に事前に割り当て、次の場合に再割り当てすることです。
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
final
変数宣言を使用することです。
Eclipseでこのエラーを取得する1つの方法:
A
を定義しsrc/test/java
ます。B
を定義src/main/java
しますA
。結果:Eclipseはコードをコンパイルしますが、mavenは「シンボルが見つかりません」と表示します。
根本的な原因:Eclipseは、メインツリーとテストツリーに結合ビルドパスを使用しています。残念ながら、これはEclipseプロジェクトの異なる部分に異なるビルドパスを使用することをサポートしていません。
解決 :
「見つかりません」とは、適切な変数、メソッド、クラスなどを見つけられないコンパイラがエラーメッセージを受け取った場合、まず最初に、エラーメッセージを受け取るコード行を見つけます。それを使用する前に、どの変数、メソッド、またはクラスが定義していないかを見つけることができます。確認後、その変数、メソッド、またはクラスを初期化して、後でrequire ...次の例を検討してください。
デモクラスを作成して名前を印刷します...
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
結果を見てください。
そのエラーは、「変数名が見つかりません」と言います。「 'name」変数の値の定義と初期化は、そのエラーを廃止できます。
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
新しい出力を見てください...
Okはそのエラーを正常に解決しました。同時に、「メソッドが見つかりません」または「クラスが見つかりません」という問題が発生した場合は、最初にクラスまたはメソッドを定義し、それを使用します。
私もこのエラーを受け取りました。(私はググってこのページにリダイレクトされました)
問題:プロジェクトAのクラスで定義された静的メソッドを、別のプロジェクトBで定義されたクラスから呼び出していました。次のエラーが発生しました:
error: cannot find symbol
解決策:最初にメソッドが定義されているプロジェクトをビルドし、次にメソッドが呼び出されているプロジェクトをビルドすることで、これを解決しました。
日食Javaビルドパスが7、8にマップされ、プロジェクトpom.xmlでMavenプロパティjava.versionが7,8より高いJavaバージョン(9、10、11など)と記載されている場合、pomで更新する必要があります。 xmlファイル。
Eclipseでは、JavaがJavaバージョン11にマッピングされ、pom.xmlでJavaバージョン8にマッピングされます。EclipseIDEヘルプ->新しいソフトウェアのインストール->の以下の手順を実行して、EclipseサポートをJava 11に更新します。
次のリンクを貼り付けhttp://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With
または
追加(ポップアップウィンドウが開きます)->
Name:
Java 11のサポート
Location:
http://download.eclipse.org/eclipse/updates/4.9-P-builds
次に、以下のようにpom.xmlファイルのMavenプロパティのJavaバージョンを更新します
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
最後にプロジェクトを右クリックして、Debug as-> Maven clean、Maven build stepsを実行します
私の場合-以下の操作を実行する必要がありました:
context.xml
からファイルをsrc/java/package
するresource
ディレクトリ(IntelliJのIDE)target
ディレクトリ。