HOWTO · Java
Java の `<identifier> expected` エラーを修正する方法
javac が示す `<identifier> expected` の意味と、パラメーター名の欠落、文の誤配置、無効な try-with-resources 構文の修正方法を説明します。
このページの内容
Java コンパイラーは、変数名、メソッド名、クラス名などの名前が必要な位置でトークンに到達すると、<identifier> expected を報告します。javac が示した行と、そのカーソルの直前にある宣言または文を確認してください。パラメーターの型や名前の欠落、クラス本体内の実行文、無効なリソース宣言がよくある原因です。
<identifier> expected の診断を理解する
識別子は Java プログラムの要素に名前を付けます。Java の識別子には文字、数字、$、_ を含められますが、数字で始めたり予約語にしたりできません。パラメーター宣言には型と識別子の両方が必要です(例: int count)。クラス本体にはフィールドや初期化ブロックを置けますが、単独の代入やメソッド呼び出しは置けません。
javac は文法を続けられなくなった位置を示しますが、そこが根本原因とは限りません。示されたトークンを変更する前に、前の行の波括弧、セミコロン、コンマ、括弧を確認してください。最初の診断を直した後に再コンパイルします。後続のメッセージは同じ構文エラーの結果かもしれません。
パラメーターの型または名前の欠落を修正する
メソッドの各パラメーターには、データ型と変数名が必要です。次の宣言では型がありません。
public class Demo {
static int square(x) {
return x * x;
}
}
この無効な形式を javac でコンパイルすると、次のような診断になります(行番号とカーソルは JDK により異なる場合があります)。
Demo.java:2: error: <identifier> expected
static int square(x) {
^
1 error
修正した宣言では x の前に int を追加します。
public class Demo {
static int square(int x) {
return x * x;
}
public static void main(String[] args) {
System.out.println(square(10));
}
}
javac Demo.java でコンパイルし、java Demo で実行すると、出力は次のようになります。
100
逆の誤りも失敗します。static int square(int) には型がありますが、パラメーター識別子がありません。名前を追加し、メソッド本体でも同じ名前を使います。class や return のような予約語ではなく、value のような有効な識別子を選んでください。
たとえば static int square(int) では javac がパラメーター名を期待するため、同じ診断が出ます。
Demo.java:2: error: <identifier> expected
static int square(int) {
^
1 error
実行文をメソッドまたは初期化ブロックへ移す
フィールドはクラスに直接宣言できますが、代入やメソッド呼び出しはメソッド、コンストラクター、または初期化ブロック内に置く必要があります。次のクラス本体は無効です。
public class Demo {
private String name;
name = "Naruto";
System.out.println(name);
}
コンパイラーは、クラス本体の文法が宣言またはブロックを期待するトークン位置を報告します。
Demo.java:3: error: <identifier> expected
name = "Naruto";
^
Demo.java:4: error: <identifier> expected
System.out.println(name);
^
3 errors
実行文をメソッドに移し、main から呼び出します。
public class Demo {
private String name;
void print() {
name = "Naruto";
System.out.println(name);
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.print();
}
}
成功時の出力は次のとおりです。
Naruto
代入をフィールドの初期化に使うなら、インスタンス初期化子({ name = "Naruto"; })も有効です。フィールド初期化子で private String name = "Naruto"; のような式も使えますが、初期化子やメソッドの外に単独のメソッド呼び出しは置けません。
try-with-resources でリソースを正しく宣言する
リソース指定部には BufferedReader reader = ... のような宣言、または初期化済みの final/実質 final 変数への参照を指定できます。既存の変数へ新しいリソースを代入する形式は宣言ではありません。
import java.io.BufferedReader;
import java.io.StringReader;
public class Demo {
public static void main(String[] args) throws Exception {
BufferedReader reader = null;
try (reader = new BufferedReader(new StringReader("Java"))) {
System.out.println(reader.readLine());
}
}
}
テストした JDK では、すでに宣言した reader への代入はリソース指定部で拒否されます。
Demo.java:7: error: the try-with-resources resource must either be a variable declaration or an expression denoting a reference to a final or effectively final variable
try (reader = new BufferedReader(new StringReader("Java"))) {
^
1 error
代わりに try 内でリソースを宣言します。
import java.io.BufferedReader;
import java.io.StringReader;
public class Demo {
public static void main(String[] args) throws Exception {
try (BufferedReader reader = new BufferedReader(new StringReader("Java"))) {
System.out.println(reader.readLine());
}
}
}
出力は次のとおりです。
Java
修正後の形式では、try ブロックの終了時に reader が自動的に閉じられます。後で必要な値はリソースが開いている間にコピーし、ブロック後に閉じたリソースを使わないでください。
再コンパイル前のチェックリスト
<identifier> expected が残る場合は、次の境界を順に確認します。
- すべてのパラメーターに型と名前があることを確認する。
- 名前が予約語でなく、数字で始まらず、意図した大文字小文字であることを確認する。
- 代入、メソッド呼び出しなどの実行文をメソッド、コンストラクター、初期化子へ移す。
- 前の行の波括弧と句読点を確認する。
- try-with-resources では宣言、または事前に初期化した実質 final リソースを使う。
これらは安定した Java 構文の規則で、Java SE 27 を含む現在の JDK に適用されます。コンパイラーのバージョンにより診断の文言や行番号は変わるため、メッセージとカーソルは周囲の文法への手掛かりとして扱い、元の誤りを必ず指すとは考えないでください。