- JAVA
Javaコンパイルエラー一覧|cannot find symbol他20種と対処法
Javaのコンパイルエラーとは、javac がソースコードを .class ファイルに変換する段階で見つけた、文法や型の誤りのことです。 プログラムは1行も実行されず、エラー文に書かれた「ファイル名:行番号」と ^ の位置を手がかりに直します。
この記事では、よく出るコンパイルエラー 25種を OpenJDK 21.0.10 の javac で実際に出し、英語メッセージ全文と日本語環境のメッセージ(-J-Duser.language=ja で出力)、原因、修正方法を1つの表にまとめました。さらに、検索の多い cannot find symbol(シンボルを見つけられません)の原因7パターンを個別に再現し、エラー文の読み方、IDE やビルドツールでの対処、実行時エラーとの違いまで解説します。
Javaコンパイルエラーの早見表(25種)
英語でも日本語でも、表の「メッセージ」列で検索すれば原因と直し方がわかります。 いずれも OpenJDK 21.0.10 の javac で実際に出力したものです(日本語は javac -J-Duser.language=ja で出力)。
| No | 英語メッセージ | 日本語メッセージ | 主な原因 | 直し方 |
|---|---|---|---|---|
| 1 | cannot find symbol | シンボルを見つけられません | 名前の綴り・import・スコープ | 綴りと import を確認(後述7パターン) |
| 2 | incompatible types: String cannot be converted to int | 不適合な型: Stringをintに変換できません: | 型が違う値を代入 | Integer.parseInt("10") |
| 3 | incompatible types: possible lossy conversion from double to int | 不適合な型: 精度が失われる可能性があるdoubleからintへの変換 | 大きい型から小さい型へ代入 | (int) price や Math.round |
| 4 | missing return statement | return文が指定されていません | 戻り値を返さない経路がある | 最後に return 0; など |
| 5 | unreported exception IOException; must be caught or declared to be thrown | 例外IOExceptionは報告されません。スローするには、捕捉または宣言する必要があります | チェック例外を処理していない | try-catch か throws IOException |
| 6 | variable total might not have been initialized | 変数totalは初期化されていない可能性があります | 初期化されない経路がある | int total = 0; |
| 7 | unreachable statement | この文に制御が移ることはありません | return の後に文がある |
不要な文を消す・順序を直す |
| 8 | class Main is public, should be declared in a file named Main.java | クラス Mainはpublicであり、ファイルMain.javaで宣言する必要があります | ファイル名とクラス名が違う | ファイル名を Main.java に |
| 9 | ';' expected | ';'がありません | セミコロン忘れ | 行末に ; |
| 10 | reached end of file while parsing | 構文解析中にファイルの終わりに移りました | } が足りない |
対応する } を追加 |
| 11 | non-static variable count cannot be referenced from a static context | staticでない変数 countをstaticコンテキストから参照することはできません | static メソッドからインスタンス変数 | インスタンスを作る・static にする |
| 12 | non-static method run() cannot be referenced from a static context | staticでないメソッド run()をstaticコンテキストから参照することはできません | static メソッドからインスタンスメソッド | new Main().run() |
| 13 | variable id is already defined in method main(String[]) | 変数 idはすでにメソッド main(String[])で定義されています | 同じ名前の変数を2回宣言 | 名前を変える |
| 14 | method add in class Main cannot be applied to given types; | クラス Mainのメソッド addは指定された型に適用できません。 | 引数の数・型が違う | 定義に合わせて渡す |
| 15 | Circle is not abstract and does not override abstract method area() in Shape | Circleはabstractでなく、Shape内のabstractメソッドarea()をオーバーライドしません | インターフェースのメソッド未実装 | area() を実装 |
| 16 | stock has private access in Item | stockはItemでprivateアクセスされます | 他クラスの private にアクセス | getter を用意 |
| 17 | unclosed string literal | 文字列リテラルが閉じられていません | " の閉じ忘れ |
"hello" |
| 18 | illegal start of expression | 式の開始が不正です | 式の途中で終わる・} 不足 |
式を完成させる・かっこを確認 |
| 19 | generic array creation | 汎用配列を作成します | new ArrayList<String>[3] |
List<List<String>> を使う |
| 20 | cannot assign a value to final variable max | final変数maxに値を割り当てることはできません | final 変数へ再代入 | 別の変数にする・final を外す |
| 21 | duplicate case label | caseラベルが重複しています | switch の case が重複 | 重複を消す |
| 22 | incompatible types: Object cannot be converted to String | 不適合な型: ObjectをStringに変換できません: | 親の型から子の型へ代入 | instanceof で確認してキャスト |
| 23 | local variables referenced from a lambda expression must be final or effectively final | ラムダ式から参照されるローカル変数は、finalまたは事実上のfinalである必要があります | ラムダで使う変数を後で変更 | 変更用の別変数を使う |
| 24 | package util does not exist | パッケージutilは存在しません | クラスパスに依存先がない | -cp を指定・依存を追加 |
| 25 | call to super must be first statement in constructor | superの呼出しはコンストラクタの先頭文である必要があります | super(...) の前に文がある |
Java 21 では先頭に移す(Java 25 では条件つきで可) |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Javaコンパイルエラー一覧|cannot find symbol他20種と対処法」
エラー文の読み方(行番号・^ の位置・最初のエラー)
javac のエラー文は「ファイル名:行番号: error: メッセージ」「問題の行」「^ で示す位置」「補足情報」の順で出ます。
Main.java:4: error: cannot find symbol
System.out.println(cout);
^
symbol: variable cout
location: class Main
1 error
| 部分 | 読み方 |
|---|---|
Main.java:4 |
Main.java の 4行目 |
error: cannot find symbol |
エラーの種類(この文で検索する) |
System.out.println(cout); |
問題のある行がそのまま表示される |
^ |
javac が問題を検出した位置(ここでは cout の先頭) |
symbol: variable cout |
見つからなかったもの(変数 cout) |
location: class Main |
探した場所(クラス Main の中) |
1 error |
エラーの総数 |
ポイント1:^ の位置は「原因」ではなく「気づいた場所」
^ は javac が矛盾に気づいた位置で、原因はそれより前にあることがよくあります。 次の例は、5行目の if の } を閉じ忘れたコードです。
public class Main {
public static void main(String[] args) {
if (args.length > 0) {
System.out.println("引数あり");
System.out.println("終了");
}
static int twice(int n) {
return n * 2;
}
}
Main.java:9: error: illegal start of expression
static int twice(int n) {
^
1 error
エラーは9行目ですが、原因は5行目の } 不足です。} が1つ足りないため、javac は main メソッドがまだ続いていると判断し、メソッドの中に static int twice が現れたことを「式の開始が不正」と報告しました。illegal start of expression や reached end of file while parsing が出たら、エラー行より上のかっこの対応を確認します。IDE の「対応するかっこのハイライト」や自動整形(インデントのずれ)で見つけやすくなります。
ポイント2:最初のエラーから直す
エラーが複数出たら、いちばん上のエラーから直して再コンパイルします。 1つの誤りが後ろに連鎖して別のエラーを生むことがあるためです。逆に、構文エラーがあると型のエラーが報告されないこともあります。
public class Main {
public static void main(String[] args) {
int total = 0
for (int i = 0; i < 3; i++) {
total += i;
}
System.out.println(totl);
}
}
Main.java:3: error: ';' expected
int total = 0
^
1 error
7行目の totl(綴りの誤り)は、この時点では報告されませんでした。 javac はまず構文(文法)を解析し、構文エラーがあるとそこで止まって、名前や型の検査に進まないためです。3行目を直して再コンパイルすると、次に cannot find symbol が出ます。「1つ直したら別のエラーが出た」のは、前進している証拠です。
| 段階 | 主なエラー | 特徴 |
|---|---|---|
| 1. 構文解析 | ';' expected、illegal start of expression、reached end of file while parsing、unclosed string literal |
文法の誤り。これがあると次の段階に進まない |
| 2. 名前・型の解決 | cannot find symbol、incompatible types、cannot be applied to given types |
名前が見つからない・型が合わない |
| 3. フロー解析 | missing return statement、might not have been initialized、unreachable statement、unreported exception |
実行経路を調べて見つかる誤り |
ポイント3:日本語メッセージと英語メッセージ
javac のメッセージは OS の言語設定に合わせて切り替わります。 日本語環境の Windows や IDE では「シンボルを見つけられません」と表示され、英語環境では「cannot find symbol」と表示されます。手元で切り替えるには次のように指定します(OpenJDK 21.0.10 で確認)。
# 日本語で表示
javac -J-Duser.language=ja Main.java
# 英語で表示(英語のほうが検索で情報が見つかりやすい)
javac -J-Duser.language=en Main.java
日本語では エラー: シンボルを見つけられません、シンボル: 変数 cout、場所: クラス Main、エラー1個 と表示されました。日本語で分からないときは英語で出し直して検索すると情報が見つかりやすくなります。
cannot find symbol の原因7パターン
cannot find symbol(シンボルを見つけられません)は「その名前の変数・メソッド・クラスが、その場所からは見つからない」という意味です。 symbol: 行が「何が」、location: 行が「どこで探したか」を示します。7つの原因を実際に再現しました。
| No | 原因 | symbol 行の例 | 直し方 |
|---|---|---|---|
| 1 | 綴りの誤り | variable cout |
宣言した名前と揃える |
| 2 | import 忘れ | class ArrayList |
import java.util.ArrayList; |
| 3 | スコープ(有効範囲)の外 | variable last |
宣言をブロックの外へ |
| 4 | 大文字小文字の違い | class string |
String、System |
| 5 | その型にないメンバー | method size()/variable length |
length() など正しい名前 |
| 6 | クラスパスに依存先がない | variable TextUtil(+package util does not exist) |
-cp やビルド設定に追加 |
| 7 | 別モジュールのパッケージ | package java.sql is not visible |
module-info.java に requires |
1. 綴りの誤り
冒頭の例(count を cout と書いた)がこれです。symbol: variable cout に表示された名前と、宣言した名前を見比べます。
int count = 3;
System.out.println(count); // 直した後
2. import 忘れ
Main.java:5: error: cannot find symbol
List<String> names = new ArrayList<>();
^
symbol: class ArrayList
location: class Main
1 error
import java.util.List; だけで ArrayList を import していませんでした。symbol: class ... と出たら import を確認します。
import java.util.ArrayList;
import java.util.List;
java.lang パッケージ(String、Math、Integer など)は import 不要です。IDE では未 import のクラス名にカーソルを置くと import を追加する候補が出ます。
3. スコープの外で使っている
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
int last = i;
}
System.out.println(last);
}
}
Main.java:6: error: cannot find symbol
System.out.println(last);
^
symbol: variable last
location: class Main
1 error
{ } の中で宣言した変数は、その } までしか使えません。 ブロックの外で使うなら、外で宣言します。
int last = -1;
for (int i = 0; i < 3; i++) {
last = i;
}
System.out.println(last);
4. 大文字小文字の違い
string name = "RJC";
system.out.println(name);
Main.java:3: error: cannot find symbol
string name = "RJC";
^
symbol: class string
location: class Main
Main.java:4: error: package system does not exist
system.out.println(name);
^
2 errors
Java は大文字と小文字を区別します。 string ではなく String、system ではなく System です。system.out は「system というパッケージの out」と解釈され、package system does not exist という別のメッセージになりました。
5. その型に存在しないメソッド・フィールド
Main.java:4: error: cannot find symbol
int n = s.length;
^
symbol: variable length
location: variable s of type String
1 error
Main.java:4: error: cannot find symbol
System.out.println(s.size());
^
symbol: method size()
location: variable s of type String
1 error
location: variable s of type String は「String 型の変数 s の中を探したが無かった」という意味です。 文字列の長さは s.length()(メソッド)、配列は arr.length(フィールド)、List は list.size() と、型によって名前が違います。
| 型 | 要素数・長さ |
|---|---|
| 配列 | arr.length |
| String | s.length() |
| List/Set/Map | list.size() |
6. クラスパスに依存先がない
別ディレクトリ・別 jar のクラスを使うとき、コンパイル時にその場所を教えないと見つかりません。util/TextUtil.java をコンパイルした結果を o3u に置き、app/Main.java を単独でコンパイルした例です。
Main.java:3: error: package util does not exist
import util.TextUtil;
^
Main.java:7: error: cannot find symbol
System.out.println(TextUtil.shout("hello"));
^
symbol: variable TextUtil
location: class Main
2 errors
-cp(-classpath)で依存先の場所を指定すると通ります。
javac -d o3u util/TextUtil.java
javac -cp o3u -d o3a app/Main.java
java -cp o3a:o3u app.Main # Windows では区切りが ; になります
HELLO!
Maven や Gradle では、pom.xml/build.gradle に依存関係を書き忘れている、またはダウンロードに失敗していると同じエラーになります(後述)。
7. 別モジュールのパッケージ(module-info.java)
module-info.java があるプロジェクト(モジュール)で、requires していないモジュールのパッケージを使った例です。
// module-info.java
module app {
}
app/Main.java:3: error: package java.sql is not visible
import java.sql.Connection;
^
(package java.sql is declared in module java.sql, but module app does not read it)
1 error
日本語環境では「パッケージjava.sqlは表示不可です」と表示されました。かっこ内の説明どおり、module app が java.sql モジュールを読み込んでいないのが原因です。 requires を追加します。
module app {
requires java.sql;
}
ライブラリ側のパッケージが exports されていない場合も「not visible」になります。その場合は公開されている API を使うか、ライブラリの提供元の案内に従います。
主なコンパイルエラーの再現と修正
早見表の各エラーを、実際の出力と直し方で確認します。出力はすべて OpenJDK 21.0.10 の javac によるもので、エラー行の内容が出力に含まれるため、再現コードは出力の2行目で確認できます(全体は public class Main { public static void main(String[] args) { ... } } の中に書いたものです)。
型に関するエラー(incompatible types)
Main.java:3: error: incompatible types: String cannot be converted to int
int n = "10";
^
Main.java:4: error: incompatible types: possible lossy conversion from double to int
int yen = price;
^
Main.java:4: error: incompatible types: Object cannot be converted to String
String s = o;
^
(3つの別ファイルの出力を並べています。各ファイル 1 error。)
| エラー | 直す前 | 直した後 |
|---|---|---|
| String → int | int n = "10"; |
int n = Integer.parseInt("10"); |
| double → int | int yen = price; |
int yen = (int) price;(切り捨て)/(int) Math.round(price)(四捨五入) |
| Object → String | String s = o; |
if (o instanceof String s) { ... } |
possible lossy conversion は「小数点以下や桁が失われる可能性がある」という警告的なエラーです。キャストで明示すれば通りますが、意図した丸め方かを確認します。金額のように誤差を避けたい計算は既存記事「Java BigDecimalの使い方」も参考になります。
return・初期化・到達不能(フロー解析のエラー)
Main.java:8: error: missing return statement
}
^
Main.java:7: error: variable total might not have been initialized
System.out.println(total);
^
Main.java:4: error: unreachable statement
System.out.println("done");
^
(3つの別ファイルの出力を並べています。)
javac は「すべての実行経路」を調べます。 missing return statement の再現コードは、if (x > 0) return 1; else if (x < 0) return -1; で終わり、x == 0 のときに return がありませんでした。
// 直す前
static int sign(int x) {
if (x > 0) {
return 1;
} else if (x < 0) {
return -1;
}
}
// 直した後
static int sign(int x) {
if (x > 0) {
return 1;
} else if (x < 0) {
return -1;
}
return 0;
}
might not have been initialized は if の中でしか代入していない変数を、if の外で使ったときに出ました。宣言時に初期値を入れる(int total = 0;)か、else でも代入します。 unreachable statement は return; の直後に文があったためです。
チェック例外(unreported exception)
Main.java:5: error: unreported exception IOException; must be caught or declared to be thrown
String text = Files.readString(Path.of("memo.txt"));
^
IOException のようなチェック例外は、try-catch で処理するか throws IOException で呼び出し元に任せます。
try {
String text = Files.readString(Path.of("memo.txt"));
} catch (IOException e) {
System.err.println("読み込みに失敗しました: " + e.getMessage());
}
例外処理の設計は既存記事「Javaの例外処理|実務で守りたいルールとよくある書き方の改善例」、ファイル操作は「Java ファイル読み込み・書き込み|Filesの逆引き表と実行結果」で詳しく扱っています。
構文エラー(; expected・end of file・文字列・式)
Main.java:3: error: ';' expected
int a = 1
^
Main.java:4: error: reached end of file while parsing
}
^
Main.java:3: error: unclosed string literal
String s = "hello;
^
Main.java:3: error: illegal start of expression
int x = (1 + );
^
(4つの別ファイルの出力を並べています。直し方は早見表のとおりです。)
';' expected の ^ は、セミコロンを置くべき位置(行末の直後)を指します。 前の行の末尾を見てください。
static に関するエラー
Main.java:4: error: non-static variable count cannot be referenced from a static context
count++;
^
Main.java:4: error: non-static method run() cannot be referenced from a static context
run();
^
static な main メソッドからは、インスタンス(new で作ったオブジェクト)に属する変数・メソッドを直接使えません。
new Main().run(); のようにインスタンスを作って呼びます。 練習用なら static void run() にしても通りますが、状態(フィールド)を持つクラスではインスタンスを作る形が自然です。
宣言・引数・アクセスに関するエラー
Main.java:4: error: variable id is already defined in method main(String[])
String id = "A";
^
Main.java:4: error: method add in class Main cannot be applied to given types;
System.out.println(add(1));
^
required: int,int
found: int
reason: actual and formal argument lists differ in length
Main.java:8: error: stock has private access in Item
System.out.println(item.stock);
^
Main.java:4: error: cannot assign a value to final variable max
max = 20;
^
cannot be applied to given types は required:(定義の引数)と found:(渡した引数)を見比べます。 日本語では「期待値: int,int」「検出値: int」「理由: 実引数リストと仮引数リストの長さが異なります」と表示されました。
has private access は、private int stock を別クラスから読もうとしたためです。getter(public int getStock() { return stock; })を用意して呼びます。 値を持つだけのクラスなら record も便利です(既存記事「Java recordの使い方」)。
クラス・インターフェースに関するエラー
Sample.java:1: error: class Main is public, should be declared in a file named Main.java
public class Main {
^
Main.java:5: error: Circle is not abstract and does not override abstract method area() in Shape
class Circle implements Shape {
^
public class の名前とファイル名は一致させます(大文字小文字も含めて)。1ファイルに public class は1つまでです。インターフェースを implements したら、すべての抽象メソッドを実装します。
class Circle implements Shape {
private final double r = 1.0;
@Override
public double area() { return Math.PI * r * r; }
}
@Override を付けておくと、メソッド名や引数を誤ったときに「オーバーライドしていない」というエラーで気づけます。
ジェネリクス・switch・ラムダのエラー
Main.java:5: error: generic array creation
List<String>[] lists = new ArrayList<String>[3];
^
Main.java:6: error: duplicate case label
case "A" -> System.out.println("重複");
^
Main.java:4: error: local variables referenced from a lambda expression must be final or effectively final
Runnable r = () -> System.out.println(x);
^
| エラー | 原因 | 直した後 |
|---|---|---|
generic array creation |
ジェネリクス型の配列は作れない | List<List<String>> lists = new ArrayList<>(); |
duplicate case label |
同じ値の case が2つ | 重複を消す |
...must be final or effectively final |
ラムダ内で使う x を後で x++ |
int fixed = x; を作ってラムダで使う |
ラムダが使えるのは「一度代入したら変わらない(事実上 final の)」ローカル変数だけです。後から値を変える変数はラムダの外で別に管理します。ラムダの基本は既存記事「Java ラムダ式の使い方」を参照してください。
super の位置(Java 21 と Java 25 で扱いが変わる)
class Child extends Base {
Child(int v) {
if (v < 0) throw new IllegalArgumentException("負の値");
super(v);
}
}
Main.java:8: error: call to super must be first statement in constructor
super(v);
^
1 error
Java 21 では super(...) をコンストラクタの先頭に書く必要があります。 引数の検証を先に行いたい場合は、static メソッドで検証してから渡す形にします。
Child(int v) {
super(check(v));
}
private static int check(int v) {
if (v < 0) throw new IllegalArgumentException("負の値");
return v;
}
Java 25 では JEP 513(Flexible Constructor Bodies)が正式機能になり、this を使わない文であれば super(...) の前に書けるようになりました。 Java 25 は手元で実行していないため、詳細は JEP 513 の公式ページで確認してください。
Java 21 で void main() だけのファイルを書いた場合
void main() {
System.out.println("hello");
}
Main.java:1: error: unnamed classes are a preview feature and are disabled by default.
void main() {
^
(use --enable-preview to enable unnamed classes)
1 error
日本語では「無名クラスはプレビュー機能であり、デフォルトで無効になっています。」と表示されました。Java 21 ではクラス宣言のない void main() はプレビュー機能で、--enable-preview --release 21 を付けるとコンパイルできました。 Java 25 では JEP 512(Compact Source Files and Instance Main Methods)として正式機能になっています(公式の JDK 25 ページで確認。手元では未実行)。学習用の短いコードを書くときに、使っている JDK のバージョンでエラーの有無が変わる点に注意します。
IDE・Maven・Gradle でコンパイルエラーが出るときの対処
コードは正しいのに IDE だけでエラーになる、ビルドツールでだけ cannot find symbol になる、という場合は、キャッシュや依存関係の読み込みが原因のことがあります。 この節の手順は手元では実行しておらず、各公式ドキュメントで確認した内容です。
| 環境 | 症状 | 対処 |
|---|---|---|
| IntelliJ IDEA | 赤い波線が消えない、存在するクラスが見つからない | File → Invalidate Caches… → Invalidate and Restart(再起動後にキャッシュが削除される) |
| IntelliJ IDEA | pom.xml/build.gradle を変更したのに反映されない | Maven/Gradle ツールウィンドウから再読み込み(Reload) |
| Eclipse | クラスが見つからない、前回のエラー表示が残る | Project → Clean... で再ビルド。Maven プロジェクトは Maven → Update Project... |
| Maven | 依存クラスが cannot find symbol |
mvn clean compile。依存の再取得は mvn -U clean compile |
| Gradle | 依存クラスが cannot find symbol |
./gradlew clean build。依存の再取得は --refresh-dependencies |
| 共通 | JDK のバージョン違いで新しい API が見つからない | IDE のプロジェクト SDK、Maven の maven.compiler.release、Gradle の toolchain を揃える |
ビルドツールのエラーも、中身は javac のメッセージです。 Maven(maven-compiler-plugin)では、ファイルパスの後ろに [行,列] が付いた形で表示されます(手元では Maven Central に接続できないため未実行)。まずコマンドラインで mvn clean compile や ./gradlew build を実行し、IDE 固有の問題かどうかを切り分けると原因を絞り込めます。
コンパイルエラーと実行時エラーの違い
コンパイルエラーは javac の段階で見つかり、実行時エラー(例外)はプログラムを動かしている途中で発生します。 クラスパスの例で、コンパイルは成功したのに、実行時に依存クラスが見つからない状況を再現しました。
javac -d o3u util/TextUtil.java
javac -cp o3u -d o3a app/Main.java # コンパイルは成功
java -cp o3a app.Main # 実行時に o3u を指定し忘れた
Exception in thread "main" java.lang.NoClassDefFoundError: util/TextUtil
at app.Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: util.TextUtil
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
... 1 more
| 比較 | コンパイルエラー | 実行時エラー(例外) |
|---|---|---|
| 発生するタイミング | javac 実行時 |
java 実行中 |
| 表示の形 | Main.java:4: error: ... |
Exception in thread "main" java.lang.XxxException |
| プログラムの実行 | されない(.class ができない) | 途中まで実行される |
| クラスが見つからない | cannot find symbol/package ... does not exist |
NoClassDefFoundError/ClassNotFoundException |
| 代表例 | 本記事の25種 | NullPointerException、ArrayIndexOutOfBoundsException、NumberFormatException |
| 直す手がかり | 行番号と ^ |
スタックトレースの自分のコードの行 |
同じ「クラスが見つからない」でも、コンパイル時はクラスパスの -cp、実行時は java -cp の指定を確認します。 実行時エラーの代表である NullPointerException は既存記事「NullPointerExceptionの原因と対処法【Java】」で詳しく解説しています。
よくある質問
Q. 「シンボルを見つけられません」と「cannot find symbol」は同じエラーですか?
A. 同じです。javac のメッセージは OS の言語設定で切り替わり、日本語環境では「シンボルを見つけられません」、英語環境では「cannot find symbol」と表示されます。javac -J-Duser.language=en で英語に切り替えられます。
Q. エラーが大量に出ました。どこから直せばよいですか? A. いちばん上のエラーから直して再コンパイルします。1つのかっこ不足が後続の多数のエラーを生むことがあり、逆に構文エラーがあると型のエラーが報告されないこともあります。
Q. エラーの行を見ても問題が見つかりません。
A. ^ は javac が気づいた位置で、原因はそれより前にあることがあります。特に illegal start of expression や reached end of file while parsing は、上の行のかっこ { } の対応を確認します。
Q. IDE ではエラーなのにコマンドラインではコンパイルできます。 A. IDE のキャッシュや依存関係の読み込みが最新でない可能性があります。IntelliJ IDEA なら File → Invalidate Caches…、Eclipse なら Project → Clean... を試し、プロジェクトの JDK バージョンも確認します。
まとめ
- コンパイルエラーは
javacの段階の誤りで、「ファイル名:行番号」と^の位置から直します。 ^は気づいた場所で、原因はその前にあることがあるので、かっこの対応を上へたどります。- エラーはいちばん上から直す。 構文エラーがあると型のエラーはまだ報告されません。
cannot find symbolは綴り・import・スコープ・大文字小文字・型のメンバー・クラスパス・モジュールの7パターンで確認します。- 日本語メッセージは
-J-Duser.language=ja、英語はenで切り替えられ、英語で検索すると情報が見つかりやすくなります。 - IDE だけのエラーはキャッシュ削除や再読み込み、ビルドツールでは依存関係と JDK バージョンを確認します。
- Java 25 では
super(...)前の文やクラス宣言なしのvoid main()が正式に使え、Java 21 とはエラーの有無が変わります。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Javaコンパイルエラー一覧|cannot find symbol他20種と対処法」
株式会社RJCでは、Javaのコンパイルエラーの読み解き方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。