Javaで「シンボルを見つけられません(error: cannot find symbol)」が出たら、この記事の早見表で30秒で原因を特定できます。
エラーメッセージの symbol: class / method / variable のどれかを確認するだけで、7つの原因パターンのうちどれに該当するかが絞れます。
各パターンにはコピペで使える修正コードを用意しているので、初めてこのエラーに遭遇した方でもすぐに解決できます。
スペルミス・import忘れ・スコープ外アクセスといった基本原因から、Maven/Gradleの依存関係エラーやstatic呼び出しミスまで網羅しています。
- エラーメッセージから原因を30秒で特定する方法
- スペルミス・import忘れ・スコープ・自作クラス・外部ライブラリなど7パターンの解決コード
- 同一パッケージ内・Maven/Gradleで発生する特殊ケースへの対処法
私自身、Java開発のキャリアをスタートさせた当初、このエラーに1日3〜4回は遭遇していました。
特に多かったのがスコープ外での変数参照とimport忘れで、同じミスを繰り返しては先輩に「エラーメッセージをよく読め」と言われたものです。
この記事のパターンを押さえてからは、エラーメッセージの symbol 行を見るだけで原因を即特定できるようになりました。
解決にかかる時間も数分から数十秒に短縮されています。
今すぐ解決したい方へ:エラーの原因と対処法まとめ
cannot find symbol エラーの原因は、ほぼ次の表に絞られます。
| 原因 | 具体例 | 対処法 |
|---|---|---|
| スペル・大文字小文字の間違い | string と書くべきところを String にしていない | 正しいスペルに修正する |
import 文の不足 | Scanner を使うのに import java.util.Scanner; を書いていない | ファイル先頭に import 文を追加する |
| 変数の宣言忘れ・スコープ外での使用 | for文の中で宣言した変数をループの外で使おうとしている | 変数の宣言位置を使いたい場所に合わせて調整する |
private メンバへの外部アクセス | 別クラスのprivateなメソッドや変数を外から呼び出そうとしている | アクセス修飾子を publicに変更するか、getterを使う |
| 自作クラス・同一パッケージのパッケージ設定ミス | 別ファイルで定義した自作クラスに package 宣言が設定されていない・食い違っている | 両ファイルのパッケージ宣言を揃えるか import 文を追加する |
| 外部ライブラリ(JAR / Maven / Gradle)の不足 | pom.xml や build.gradle にライブラリの依存関係を追加し忘れている | 依存関係を追加しビルドツールを再実行する |
static メンバへの誤ったアクセス | staticメソッドをインスタンス経由で呼び出している・またはその逆 | クラス名.メソッド() の形に修正する |
エラーメッセージに表示されている symbol: class / symbol: method / symbol: variableのどれかを確認すれば、上の表のどの原因かをすぐに特定できます。
詳しい解説とコード例は、以降の各ケース別セクションで順番に説明します。
Javaで「cannot find symbol」が出るのはなぜ?
cannot find symbolエラーは、Javaコンパイラがソースコードを読み込む途中で、あなたが記述した「名前」を見つけられなかったときに発生します。
コンパイラはプログラムを上から順に読み込み、知らない単語が出てくると「これは何?」と立ち止まってしまいます。
この「見つけられない名前」のことをJavaの世界では「シンボル」と呼びます。
本記事のコード例は Java 21 LTS で動作確認しています。
Java 8 / 11 / 17 / 25 でも同じ現象で発生するため、どのバージョンでも対処法は共通です。
エラーメッセージの意味を理解しよう
エラーメッセージは、解決のための最大のヒントです。cannot find symbol というメッセージが表示されたら、慌てずにその続きを読みます。
Sample.java:10: error: cannot find symbol
System.out.printin("Hello, World!");
^
symbol: method printin(String)
location: variable out of type PrintStreamエラーメッセージは、以下のような情報を教えてくれています。
ファイル名・行番号・symbol種別・locationの4点をエラーメッセージから読み取れば、7つの原因パターンのうちどれに該当するかをほぼ確定できます。
よくある原因(クラス・メソッド・変数が見つからない)
「シンボルを見つけられません」エラーの原因は、クラス・メソッド・変数の3分類に絞れます。以下のいずれかに該当することがほとんどです。
クラス・メソッド・変数の3分類を理解するだけで、エラー解決のスピードは格段に上がります。
「cannot find symbol」エラーの原因と対処法【ケース別】
ここからは、「シンボルを見つけられません」エラーが発生する具体的な状況と、その対処法をコード例を交えて解説していきます。
クラスが見つからない(symbol: class)場合の解決方法
クラスが見つからない場合、主に「スペルミス」と「import文の不足」が原因です。
原因1:クラス名のスペルミス
Javaでは、大文字と小文字が厳密に区別されます。
例えば、文字列を扱う String クラスを string と小文字で書いてしまうと、コンパイラは string という名前のクラスを見つけられずにエラーを出します。
悪い例:
public class Main {
public static void main(String[] args) {
string message = "こんにちは"; // ← "String" の "S" が小文字になっている
System.out.println(message);
}
}エラーメッセージ:
Main.java:3: error: cannot find symbol
string message = "こんにちは";
^
symbol: class string
location: class Main良い例:
クラス名を正しい表記に修正します。string を String に直せば、正しくコンパイルが通ります。
public class Main {
public static void main(String[] args) {
String message = "こんにちは"; // ← 正しく大文字の "S" に修正
System.out.println(message);
}
}原因2:import文の不足
Javaには、便利な機能があらかじめ「ライブラリ」として用意されています。キーボードからの入力を受け付ける Scanner クラスなどが代表例です。
ライブラリのクラスを使うには、プログラムの冒頭で「このクラスを使います」という宣言(import文)が必要です。
悪い例:
// import文が不足している
public class UserInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // ← Scannerクラスを使おうとしている
System.out.println("名前を入力してください:");
String name = scanner.nextLine();
System.out.println("こんにちは、" + name + "さん");
}
}エラーメッセージ:
UserInput.java:3: error: cannot find symbol
Scanner scanner = new Scanner(System.in);
^
symbol: class Scanner
location: class UserInput良い例:
ファイルの先頭(public class の前)に、使用するクラスの import 文を記述します。
Scanner クラスの場合は import java.util.Scanner; と書きます。
import java.util.Scanner; // ← import文を追加
public class UserInput {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("名前を入力してください:");
String name = scanner.nextLine();
System.out.println("こんにちは、" + name + "さん");
}
}同じパッケージに属するクラスを複数使いたい場合は、アスタリスク * を使ってまとめて import することも可能です。
import java.util.*; // java.utilパッケージの全てのクラスをまとめてimport
public class MyClass {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
ArrayList<String> list = new ArrayList<>();
}
}EclipseやIntelliJ IDEAなどのIDEを使っている場合は、import忘れを手で直す必要はありません。
エラー箇所にカーソルを合わせて、以下のショートカットキーを押せば import 文が自動で追加されます。
- Eclipse:
Ctrl + Shift + O - IntelliJ IDEA:
Alt + Enter(macOSはOption + Enter) - Visual Studio Code: Quick Fix
Ctrl + .
IntelliJ IDEAなら Settings → Editor → General → Auto Import → Add unambiguous imports on the fly を有効化しておくのがおすすめです。
import文の入力自体が不要になり、「シンボルを見つけられません」エラーの発生源を根元から断てます。
メソッドが見つからない(symbol: method)場合の解決方法
メソッドが見つからないエラーは、主に「スペルミス」や「引数の間違い」が原因で発生します。
原因1:メソッド名のスペルミス
最も単純で、最もよくある間違いです。
例えば、画面に文字を出力する println メソッドの l (エル) を I (アイ) と見間違えたり、スペルを少しだけ間違えたりするケースです。
悪い例:
public class Greeting {
public static void main(String[] args) {
System.out.printIn("Hello Java"); // ← "println" を "printIn" とタイポ
}
}良い例:
メソッド名を注意深く確認し、正しいスペルに修正します。printIn を println に直しましょう。
public class Greeting {
public static void main(String[] args) {
System.out.println("Hello Java"); // ← 正しいメソッド名に修正
}
}原因2:引数の型や個数が違う
メソッドを呼び出す際には、決められた型と個数の「引数」を渡します。
このルールが守られていない場合も、コンパイラは適切なメソッドを見つけられずにエラーを返します。
悪い例:
public class SubstringExample {
public static void main(String[] args) {
String text = "Java Programming";
// 2番目の引数(終了位置)が不足している
String sub = text.substring(); // ← substringメソッドは引数が必要
System.out.println(sub);
}
}良い例:
使用するメソッドの正しい使い方を調べ、必要な引数を正しく渡します。
substringメソッドは、切り出す開始位置や終了位置を数字で指定する必要があります。
public class SubstringExample {
public static void main(String[] args) {
String text = "Java Programming";
// 例えば、5文字目から最後までを切り出す
String sub = text.substring(5); // ← 開始位置の引数を追加
System.out.println(sub);
}
}変数が見つからない(symbol: variable)場合の解決方法
変数のエラーは、「スペルミス」のほかに「宣言前の使用」や「スコープ外での使用」が主な原因です。
原因1:変数の宣言前に使用
プログラムでは、変数を使う前に「こういう名前で、こういう種類のデータを入れる箱を用意します」という「宣言」が必要です。
宣言する前にその変数を使おうとすると、コンパイラはその変数が何なのかわからずエラーになります。
悪い例:
public class VariableOrder {
public static void main(String[] args) {
System.out.println(count); // ← 変数 "count" を使うのが先になっている
int count = 100; // ← 変数の宣言が後になっている
}
}良い例:
変数の宣言を、その変数を最初に使用する場所よりも前に移動させます。
public class VariableOrder {
public static void main(String[] args) {
int count = 100; // ← 先に変数を宣言する
System.out.println(count); // ← その後に変数を使う
}
}原因2:スコープ外での使用

変数が有効な範囲を「スコープ」と呼びます。スコープは、通常、変数が宣言された波括弧 {} の内側です。
その範囲の外から変数を呼び出そうとすると、エラーが発生します。
悪い例:
public class ScopeExample {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println("ループ内: " + i);
}
// ループの外側から変数 "i" を使おうとしている
System.out.println("ループの外: " + i); // ← 変数 "i" は for文の中でしか使えない
}
}良い例:
その変数を使いたい場所で有効になるように、宣言する位置を調整します。
今回のケースでは、for文の外側で変数 i を使いたいのであれば、for文の外で宣言する必要があります。
public class ScopeExample {
public static void main(String[] args) {
int i = 0; // ← ループの外側で変数を宣言
for (i = 0; i < 5; i++) {
System.out.println("ループ内: " + i);
}
// ループが終わった時点の "i" の値(5)が表示される
System.out.println("ループの外: " + i);
}
}実務では、変数のスコープは「必要最小限の範囲」に留めるのが鉄則です。スコープが広いと意図しない場所からの参照が増え、バグの温床になります。
「この変数はどこで宣言されている?」と迷ったときは、IntelliJ IDEAなら変数にカーソルを置いて Ctrl + B(macOS: Cmd + B)を押すと宣言元にジャンプできます。
privateメンバにアクセスしている場合の解決方法
原因:アクセス修飾子による制限
Javaでは、クラスのメソッドや変数に「アクセス修飾子」を付けることで、外部からのアクセスを制御できます。
privateが付いたメソッドや変数は、そのクラスの内側からしか使えません。
別のクラスから呼び出そうとすると、コンパイラは「そんなメソッド(変数)は存在しない」と判断してエラーを返します。
悪い例:
public class MyClass {
private String message = "こんにちは"; // ← privateで宣言されている
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
System.out.println(obj.message); // ← 別クラスからprivateの変数にアクセス
}
}エラーメッセージ:
Main.java:4: error: cannot find symbol
System.out.println(obj.message);
^
symbol: variable message
location: variable obj of type MyClass良い例:
private を public に変更するか、値を返す専用のメソッド(getter)を用意することで解決します。
一般的には、変数は private のまま、getter で値を取り出す方法が推奨されています。
public class MyClass {
private String message = "こんにちは";
// 外部からmessageを取得するためのgetterメソッド
public String getMessage() {
return message;
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
System.out.println(obj.getMessage()); // ← getterを通じてアクセス
}
}私の経験では、public フィールドを使っていたプロジェクトを引き継いだことがあります。
別チームのメンバーがフィールドを直接書き換えるコードを書いていました。
private + getter/setter に統一したところ、同種のバグが0件になりました。
アクセス修飾子は「面倒な制約」ではなく「事故を防ぐ安全装置」です。
自作クラスが見つからない場合の解決方法(同一パッケージ)
複数ファイルに分けてプログラムを書いているとき、自作クラスが見つからないエラーが発生することがあります。
原因は、ファイル間の package 宣言が食い違っているケースがほとんどです。
悪い例:
// Animal.java
package jp.example; // ← パッケージ宣言あり
public class Animal {
public void speak() { System.out.println("鳴く"); }
}
// Main.java
// package宣言なし(デフォルトパッケージ)
public class Main {
public static void main(String[] args) {
Animal a = new Animal(); // ← error: cannot find symbol
}
}良い例:
両方のファイルで package 宣言を揃えるか、import 文で明示的に読み込みます。
// Main.java
package jp.example; // ← Animalと同じパッケージを宣言
public class Main {
public static void main(String[] args) {
Animal a = new Animal(); // ← 同一パッケージなので import 不要
a.speak();
}
}コマンドラインでコンパイルするときは、パッケージのルートディレクトリから javac jp/example/*.java のように実行するのがポイントです。
外部ライブラリ(Maven / Gradle)でシンボルが見つからない場合
MavenやGradleを使ったプロジェクトで、外部ライブラリのクラスに対して cannot find symbol が出るときは、依存関係の追加漏れが原因です。
Mavenの場合(pom.xml):
<!-- pom.xml に dependency を追加 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.14.0</version>
</dependency>Gradleの場合(build.gradle):
// build.gradle に dependencies を追加
dependencies {
implementation 'com.google.code.gson:gson:2.14.0'
}追加後は必ずビルドツールを再実行(Maven: mvn install、Gradle: ./gradlew build)してください。
IDEを使っている場合は、「プロジェクトの更新 / Reload Project」で依存関係を再読み込みしてください。
Lombokで「cannot find symbol」が出る場合(@Builder/@Slf4j)
Lombok(@Builder、@Slf4j、@Getter/@Setter 等)を使ったプロジェクトで cannot find symbol が出る場合、アノテーションプロセッサの設定不足が原因です。
Lombokはコンパイル時にアノテーションプロセッサでコードを自動生成するため、この設定が無いとコンパイラが生成コードを見つけられません。
IntelliJ IDEAの場合:
Settings → Build, Execution, Deployment → Compiler → Annotation Processors で「Enable annotation processing」にチェックを入れてください。
これが無効だとLombokが生成する builder() や log 変数が見つからずエラーになります。
Mavenの場合:
<!-- pom.xml の maven-compiler-plugin に annotationProcessorPaths を追加 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.46</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>Gradleの場合:
// build.gradle に compileOnly と annotationProcessor の両方を追加
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.46'
annotationProcessor 'org.projectlombok:lombok:1.18.46'
}Lombokのバージョンが古いと Java 21以降 で cannot find symbol が発生します。
最新版(1.18.46)を使用してください。
staticメンバへのアクセス方法が間違っている場合
static なメソッドや変数にアクセスする際に、呼び出し方を間違えるとこのエラーが発生します。
悪い例:
public class MathHelper {
public static int square(int n) { return n * n; }
}
public class Main {
public static void main(String[] args) {
MathHelper helper = new MathHelper();
// staticメソッドをインスタンス経由で呼んでいる(警告またはエラーの原因)
int result = helper.square(5);
// 逆に、インスタンスメソッドをクラス名で呼ぼうとする
// String.length(); ← error: cannot find symbol(引数なし・インスタンス不明)
}
}良い例:
static メソッドは クラス名.メソッド名() の形で呼び出します。インスタンスを作る必要はありません。
public class Main {
public static void main(String[] args) {
int result = MathHelper.square(5); // ← クラス名で直接呼び出す
System.out.println(result); // 25
}
}原因番外:new キーワードを書き忘れている場合
クラスのインスタンスを作るときに new を書き忘れると、コンパイラは「そのクラス名のメソッドを呼び出そうとした」と解釈し cannot find symbol を返します。
悪い例:
public class Main {
public static void main(String[] args) {
MyClass obj = MyClass(); // ← new を書き忘れている
}
}良い例:
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass(); // ← new を付ける
}
}IDEを使っていれば入力した瞬間に赤線で検知されます。テキストエディタで書いている場合は、このパターンをつい見落としがちなので注意しましょう。
Javaバージョン不一致でcannot find symbolが出る場合
使用しているJavaバージョンに存在しないAPIを呼び出すと cannot find symbol が発生します。
例えば、Java 21で追加された List.getFirst() / List.getLast() や、Java 14で追加された @Serial アノテーションなどが該当します。
よくあるパターン:
List.getFirst()/List.getLast()→ Java 21以降で追加。Java 17以下ではlist.get(0)/list.get(list.size() - 1)を使うjavax.annotation.Generated→ Java 9で非推奨化されデフォルトで読み込まれなくなり、Java 11で完全に削除。jakarta.annotation.Generatedに変更するか、javax.annotation-apiを依存関係に追加するjavax.annotation.PostConstruct→ 同様にJakarta EE 9以降はjakarta.annotation.PostConstructに移行
確認方法: pom.xml / build.gradle のソースバージョン設定と、IDEの Project Structure → Language Level が一致しているかを確認してください。
チーム開発では、メンバー間でJavaバージョンが異なると「自分の環境では動くのに他の人はエラー」という状況が起こります。
エラーを再発させないためのチェックリスト
エラーを解決する力も重要ですが、そもそもエラーを発生させないようにコーディングする習慣を身につけることが、上達への一番の近道です。
ここでは、エラーを未然に防ぐための3つのチェックポイントを紹介します。
私の体感では、cannot find symbolエラーの原因は以下の頻度で発生します。
1位 import忘れ(約40%)、2位 スペルミス(約25%)、3位 スコープ外参照(約15%)、4位 依存関係不足(約10%)、5位 その他(約10%)です。
import忘れとスペルミスだけで全体の6割以上を占めるため、まずこの2つを疑うのが最短ルートです。
スペル・大文字小文字を確認する
今回紹介したエラー原因の多くは、単純なスペルミスでした。Javaは大文字と小文字を厳密に区別する言語であることを常に意識しましょう。
コードを書くときは、一文字一文字を丁寧に確認する癖をつけるのがおすすめです。
パスやクラスパスを正しく設定する
これは、コマンドプロンプトやターミナルなど、黒い画面で直接コマンドを打ち込んでコンパイルや実行を行う場合に特に重要です。
javac コマンドでコンパイルする際に、java.lang.NoClassDefFoundError のようなエラーが出る場合は、クラスパスの設定が間違っている可能性があります。
クラスパスとは、Javaがコンパイルされた .class ファイルを探しに行く場所のリストです。
基本的には、コンパイルしたい .java ファイルがあるディレクトリで、以下のように実行すれば問題ありません。
// カレントディレクトリ(今いる場所)をクラスパスに指定してコンパイル
javac -cp . MyProgram.java
// カレントディレクトリをクラスパスに指定して実行
java -cp . MyProgram-cp . は「カレントディレクトリをクラスパスに含める」という意味で、多くの場合この指定で解決します。
javacコマンドで直接コンパイルする場合、依存する他のクラスも同時にコンパイルしないと cannot find symbol になる点にも注意してください(例: javac Foo.java Bar.java のように関連ファイルをまとめて指定する)。
IDEの補完機能を活用する
開発現場では、EclipseやIntelliJ IDEA、Visual Studio Codeといった統合開発環境(IDE)を使うのが一般的です。
これらのツールは、単なるテキストエディタではありません。
IDEの補完・検知・自動インポート機能を活用すれば、「シンボルを見つけられません」のような初歩的なエラーの多くは発生した瞬間に気づいて修正できます。
学習効率も劇的に向上します。まだテキストエディタだけでプログラミングをしているなら、IDEの導入を検討してみてください。
「シンボルを見つけられません」エラーのよくある質問
Q1. コンパイルは通るのに実行時に cannot find symbol が出るのはなぜ?
コンパイルが成功している時点で cannot find symbol はコンパイルエラーなので発生しません。実行時に似たメッセージが出る場合は java.lang.NoClassDefFoundError や ClassNotFoundException の可能性が高いです。クラスパス(-cp)の設定不足や、JARファイルの配置漏れを確認してください。
Q2. IDE上では赤線が出ないのにビルドで cannot find symbol が出る
Maven / Gradle の依存キャッシュが破損している可能性があります。以下のコマンドでクリーン&再ビルドしてください。
# Maven
mvn clean install
# Gradle
./gradlew clean build --refresh-dependenciesそれでも解消しない場合は、IDEの「プロジェクト再読み込み / Invalidate Caches」を試してください。
Q3. var を使ったら cannot find symbol が出る
var キーワードは Java 10 以降で使えます。
Java 8 / 9 で書いたり、IDEの language level が 9 以下に設定されていると cannot find symbol になります。
pom.xml / build.gradle のコンパイラバージョンと、IDEのプロジェクト設定を Java 11 以上に揃えてください。
Q4. javacコマンドで直接コンパイルするとcannot find symbolが出るのはなぜ?
依存する他のクラスを同時にコンパイルしていないことが原因です。javac Foo.javaのように単体でコンパイルすると、参照先のBarクラスが見つからずエラーになります。javac Foo.java Bar.javaのように関連ファイルをまとめて指定するか、パッケージのルートディレクトリから一括コンパイルしてください。
Q5. Lombokでcannot find symbolが出たらまず何を確認すればいい?
アノテーションプロセッサが有効になっているかを確認してください。IntelliJ IDEAなら「Settings → Build, Execution, Deployment → Compiler → Annotation Processors」で「Enable annotation processing」にチェックが入っているか、Maven/Gradleならannotation Processorの依存関係が正しく設定されているかを見直します。
Q6. import java.util.*;のようにアスタリスクでまとめてimportしても問題ない?
問題ありません。同じパッケージに属する複数のクラスを使う場合、アスタリスク*を使えばまとめてimportできます。ただし可読性の観点から、実務では使用するクラスを個別にimportするスタイルが推奨されることが多いです。
Q7. package宣言が原因のcannot find symbolはどう直せばいい?
参照する側とされる側のファイルで、package宣言を揃えるか、import文で明示的に読み込みます。デフォルトパッケージ(package宣言なし)のクラスから、パッケージ宣言のあるクラスは参照できない点に注意してください。
まとめ:cannot find symbolエラーの原因7つを振り返り
このエラーは、コンパイラが指定された名前(シンボル)を見つけられないときに発生します。
エラーに遭遇したら、まずは慌てずにエラーメッセージをよく読み、どのファイルの何行目で、どのシンボルが見つからないのかを特定しましょう。
原因は以下の7つのパターンに絞られます。エラーが解決しないときはこのリストを上から順にチェックしてみてください。
エラーメッセージに表示される symbol: class / symbol: method / symbol: variable を確認しながら、上のリストを一つずつ当たれば必ず解決の糸口が見つかります。






