[解決済み] Cannot find symbol" や "Cannot resolve symbol" というエラーはどういう意味ですか?
質問
Cannot find symbol"、Cannot resolve symbol"、Symbol not found"エラーについて教えてください(Javaの場合)。
- これらは何を意味するのですか?
- どのようなことが原因で起こるのですか?
- プログラマーはどのように修正するのですか?
この質問は、Javaのこれらの一般的なコンパイルエラーに関する包括的なQ&Aを種明かしするためのものです。
解決方法は?
0. この2つのエラーに違いはあるのでしょうか?
シンボルが見つかりません」、「シンボルを解決できません」、「シンボルが見つかりません」は、すべて同じ意味です。 Javaコンパイラによって、異なる表現が使われています。
1. Cannot find symbol"エラーはどういう意味ですか?
まず第一に、それは コンパイルエラー 1 . という意味です。 どちらか Java のソースコードに問題があります。 または コンパイルの仕方に問題がある。
あなたのJavaのソースコードは、次のようなもので構成されています。
-
キーワード:のような
class
,while
といった具合です。 -
リテラル:以下のような
true
,false
,42
,'X'
と"Hi mum!"
. -
演算子やその他の非英数字トークン:例えば
+
,=
,{
といった具合です。 -
識別子:以下のようなものです。
Reader
,i
,toString
,processEquibalancedElephants
といった具合です。 - コメントと空白。
Cannot find symbol"エラーは、識別子のことです。 コンパイル時に、コンパイラはコードに含まれる一つ一つの識別子が何を意味するのかを調べる必要があります。
Cannot find symbol"エラーは、コンパイラがこれを実行できないことを意味します。 あなたのコードは、コンパイラが理解できないものを参照しているように見えます。
2. Cannot find symbol"エラーの原因は何ですか?
第一法則として、原因は一つしかありません。 コンパイラは識別子 が必要です。 が定義されているのに、その定義が見つからなかったのです。 これは、いくつかの原因が考えられます。 一般的なものは以下の通りです。
-
識別子全般について。
-
おそらく名前のスペルが間違っているのでしょう。
StringBiulder
ではなくStringBuilder
. Javaは、スペルミスやタイプミスを補正することはできませんし、補正しようともしません。 -
おそらく、大文字と小文字を間違えているのでしょう。
stringBuilder
ではなくStringBuilder
. Java の識別子はすべて大文字と小文字が区別されます。 -
アンダースコアが不適切に使用されている可能性があります。
mystring
とmy_string
が違います。 (Javaのスタイルルールを守れば、この間違いからほぼ守られます.) - おそらく、あなたが使おうとしているものは、他の場所で宣言されたもので、コンパイラに暗黙のうちに指示した場所とは異なるコンテキストで宣言されています。 (別のクラス? 異なるスコープ? 別のパッケージ? 別のコードベース?)
-
おそらく名前のスペルが間違っているのでしょう。
-
変数を参照すべき識別子用。
- おそらく、変数の宣言を忘れているのでしょう。
- 使用しようとした時点で、変数宣言がスコープ外になっている可能性があります。 (下記の例参照)
-
メソッド名やフィールド名となるべき識別子の場合。
-
おそらく、親クラスや祖先クラス、インターフェイスで宣言されていない、継承されたメソッドやフィールドを参照しようとしているのでしょう。
-
おそらく、使用している型に存在しない(つまり宣言されていない)メソッドやフィールドを参照しようとしているのでしょう; 例えば
"rope".push()
2 . -
おそらく、メソッドをフィールドとして使用しようとしているか、またはその逆でしょう。
"rope".length
またはsomeArray.length()
. -
おそらく、配列の要素ではなく、配列に対して誤って操作しているのでしょう。
String strings[] = ... if (strings.charAt(3)) { ... } // maybe that should be 'strings[0].charAt(3)'
-
-
クラス名となるべき識別子の場合。
-
おそらく、クラスをインポートするのを忘れているのでしょう。
-
おそらく "star" インポートを使用しましたが、そのクラスはインポートしたどのパッケージでも定義されていないのでしょう。
-
おそらく
new
というようにString s = String(); // should be 'new String()'
-
-
型やインスタンスが、期待していたメンバー(メソッドやフィールドなど)を持っていないように見える場合に使用します。
- ネストされたクラスやジェネリックパラメータを宣言した場合、そのパラメータが シャドウ を使用する予定でした。
- おそらく、静的変数またはインスタンス変数をシャドウイングしているのでしょう。
-
IDE の補完や自動修正により、間違った型をインポートした可能性があります。
java.awt.List
ではなくjava.util.List
. - 間違ったバージョンのAPIを使用している(コンパイルしている)可能性があります。
- オブジェクトを適切なサブクラスにキャストするのを忘れている可能性があります。
- 変数の型を、探しているメンバを持つ変数の上位型と宣言している可能性があります。
問題は、多くの場合、上記の組み合わせです。 例えば、次のような場合です。
java.io.*
を使用し、その後
Files
クラス ... これは
java.nio
ではなく
java.io
. あるいは、次のように書くつもりだったのかもしれません。
File
...これは
は
のクラスです。
java.io
.
変数のスコープが正しくないと、"Cannot find symbol"エラーになる例を紹介します。
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
をループの開始前に指定します)。
タイプミスが原因で、一見不可解な "Cannot find symbol" エラーが発生する、不可解な例を紹介します。
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
ステートメントは
範囲外
をブロック内で使用します。
以下は、タイプミスが原因の "Cannot find symbol" エラーの別の例です。
int tmp = ...
int res = tmp(a + b);
前の宣言にもかかわらず
tmp
の中にある
tmp(...)
式は誤りです。 コンパイラは
tmp
ということです。 先に宣言された
tmp
は、メソッドの名前空間ではなく、変数の名前空間にあります。
私が遭遇した例では、実はプログラマーが演算子を省いていたのです。 彼が書こうとしたのは、こうだ。
int res = tmp * (a + b);
コマンドラインからコンパイルする場合、コンパイラがシンボルを見つけられない理由がもう一つあります。 単に他のクラスをコンパイルし忘れたか、再コンパイルし忘れた可能性があります。 例えば
Foo
と
Bar
ここで
Foo
用途
Bar
. をコンパイルしたことがない場合
Bar
を実行すると
javac Foo.java
というシンボルがコンパイラに見つからないことがあります。
Bar
. 簡単な答えは、コンパイルすることです。
Foo
と
Bar
を一緒に使用します。
javac Foo.java Bar.java
または
javac *.java
. あるいは、Ant, Maven, Gradle などのJavaビルドツールを使うのがよいでしょう。
その他にも、もっとわかりにくい原因があるのですが・・・それは後述します。
3. これらのエラーを修正するにはどうすればよいですか?
一般的には、まず最初に、どのような 原因 というコンパイルエラーが発生します。
- コンパイルエラーのメッセージで示されたファイルの行を見てください。
- エラーメッセージがどのシンボルについて言っているのかを確認します。
- 図解 なぜ コンパイラはそのシンボルが見つからないと言っています。
次に 考える あなたのコードが言わんとすることは何なのか。 そして最終的に 自分の望むことを実現するために ソースコードにどんな修正を加えるべきかを考えます。
ただし、すべてのquot;correction"が正しいわけではありません。これを考えてみましょう。
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
のループは、おそらく間違っています。 - といった具合です。
ポイントは、あなたが 必要 を理解することで、正しい修正方法を見つけることができます。
4. 不明確な原因
ここでは、quot;Cannot find symbol"が一見不可解に見えるケースをいくつか紹介します...よく見てみてください。
-
不適切な依存関係 : ビルドパスやプロジェクトの依存関係を管理するIDEやビルドツールを使用している場合、依存関係を間違えている可能性があります。例えば、依存関係を省いていたり、間違ったバージョンを選択していたりします。 ビルドツール(Ant、Maven、Gradleなど)を使用している場合、プロジェクトのビルドファイルを確認します。 IDEを使用している場合は、プロジェクトのビルドパスの設定を確認してください。
-
シンボル 'var' が見つかりません。 : おそらく、ローカル変数の型推論を使用するソースコードをコンパイルしようとしているのでしょう(すなわち
var
宣言)を、古いコンパイラや古い--source
レベルになります。 またvar
はJava 10で導入されました。 JDKのバージョンとビルドファイル、そして(IDEで発生した場合)IDEの設定を確認してください。 -
コンパイル/リコンパイルしていない : 新しいJavaプログラマーが、Javaツールチェーンの仕組みを理解していなかったり、IDE、Ant、Maven、Gradleなどを使って、繰り返し可能なビルドプロセスを実装していなかったりすることがあります。 このような状況では、プログラマーは、以下のような幻のエラーを探しながら、尻尾を巻いてしまうことになります。 実際に リコンパイルがうまくいっていないなど。
もう一つの例は、(Java 9+)を使用する場合です。
java SomeClass.java
を使用してクラスをコンパイルし、実行します。 そのクラスが、コンパイル(または再コンパイル)していない別のクラスに依存している場合、2番目のクラスを参照して "シンボルを解決できない"エラーが発生する可能性があります。 他のソースファイルは自動的にはコンパイルされません。 そのためjava
コマンドの新しいモードである "compile and run" は、複数のソース・コード・ファイルを持つプログラムを実行するために設計されたものではありません。 -
以前のビルドの問題 : 以前のビルドで失敗し、クラスが欠落した JAR ファイルが生成された可能性があります。 このような失敗は、ビルドツールを使っている場合、通常、気づかれるでしょう。 しかし、もしあなたが他の人から JAR ファイルを入手しているのなら、 あなたは それら が正しくビルドされ、エラーに気づくことができます。 もしこれが疑わしい場合は
tar -tvf
をクリックして、疑わしいJARファイルの内容をリストアップします。 -
IDEの問題 : IDEが混乱して、IDE内のコンパイラが存在するクラスを見つけられない・・・というケースや、その逆の状況が報告されています。
-
これは、IDEが間違ったJDKのバージョンで構成されている場合に起こる可能性があります。
-
IDE のキャッシュがファイルシステムと同期していない場合に発生する可能性があります。 これを修正するIDE固有の方法があります。
-
これはIDEのバグである可能性があります。 たとえば、@Joel Costigliola は、Eclipse が Maven の "test" ツリーを正しく扱わないというシナリオを説明しました。 この回答を見る . (どうやらその特定のバグはずっと前に修正されているようです)。
-
-
Androidの問題点 : Androidでプログラミングをしていて、以下のようなエラーが発生することがあります。
R
を使用していることに注意してください。R
シンボルが定義されています。context.xml
ファイルを作成します。 あなたのcontext.xml
ファイルが正しく、正しい場所にあり、対応するR
クラスファイルが生成/コンパイルされました。 Java のシンボルは大文字と小文字を区別するので、対応する XML の ID も大文字と小文字を区別することに注意してください。Androidにおけるその他のシンボルエラーは、先に述べた理由によるものと思われます。例えば、依存関係の欠如や不正確なパッケージ名、特定のAPIバージョンに存在しないメソッドやフィールド、スペルミスやタイピングエラーなどです。
-
システムクラスの非表示 : コンパイラが文句を言うケースを見たことがあります。
substring
は未知のシンボルであり、以下のようなString s = ... String s1 = s.substring(1);
をプログラマーが独自に作成したものであることが判明しました。
String
を定義しておらず、そのクラスのバージョンはsubstring
メソッドを使用します。 でやっている人を見たことがあります。System
,Scanner
といったクラスがあります。レッスンです。 一般的なライブラリクラスと同じ名前で独自のクラスを定義しないようにしましょう
この問題は、完全修飾名を使用することによっても解決することができます。 例えば、上記の例では、プログラマーが できる は書いている。
java.lang.String s = ... java.lang.String s1 = s.substring(1);
-
ホモグリフ。 ソースファイルのエンコーディングにUTF-8を使用した場合、識別子に 見る を含むため、同じでありながら、実際には異なっています。 参照 このページ をご覧ください。
ソースファイルのエンコードをASCIIまたはLatin-1に限定し、Javaの
\uxxxx
は他の文字をエスケープします。
1 - もし、ひょっとして、あなたが
する
このような例外やエラーメッセージが表示される場合、コンパイルエラーがあるコードを実行するようにIDEが設定されているか、アプリケーションがコードを生成して実行時にコンパイルしているかのどちらかです。
2 - 土木工学の3つの基本原則:水は坂道を流れない、板は横にした方が強い、そして
ロープで押してはいけない
.
関連
-
エラー java.util.NoSuchElementException
-
[解決済み] Javaでパラメータの型の横にある3つの点は何を意味するのですか?
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
xxx:jarのアーティファクトディスクリプタの読み込みに失敗した問題は解決しました。
-
[解決済み] Could not find or load main class "とはどういう意味ですか?
-
[解決済み] Rが解決できない - Androidエラー
-
[解決済み] シンクロナイズド」とはどういう意味ですか?
-
[解決済み] IntelliJのインスペクションで「シンボルを解決できない」と表示されたが、コードはコンパイルされる
-
[解決済み] import」の後の「static」モディファイアは何を意味するのですか?
-
[解決済み】IntelliJでMavenのプラグインが見つからない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】doubleからintへの非可逆変換の可能性があり、シンボルが見つからない【重複あり
-
アクセス制限について アプリケーションの種類がAPIでない(必要なライブラリの制限)。
-
final, finally, finalizeの違いについて話してください。
-
スキャナは、タイプに解決することはできません最もルーキー初心者の質問
-
eclipse の実行時に java 仮想マシンが見つからなかった
-
Eclipseでプロジェクトエクスプローラービューとパッケージエクスプローラービューを使う
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
Exception: java.util.NoSuchElementException: 行が見つかりません