「Java Gold(1Z0-829)の模試で、実行結果を一生懸命追ったのに、正解が『コンパイルエラー』だった」——そんな悔しい経験はありませんか。Java Goldは「このコードの実行結果を選べ」という設問が多く、選択肢のどれかに必ずコンパイルエラーが紛れ込んでいます。処理を追う前に、そもそもコンパイルが通るのかを見極める力が問われるのです。
Java Goldのコンパイルエラー系の誤答パターンは、「文法上あり得ないコード」を実行結果の設問に混ぜて、処理の追跡に気を取られた受験者を引っかける形が中心です。var・final・ジェネリクス・アクセス修飾子・switch式・try-with-resourcesなど、コンパイルを止める典型パターンを覚えておけば、実行結果を計算する前に答えが決まる問題を素早く処理できます。
この記事では、Java GoldとORACLE MASTER Goldを保有する筆者が、Java Gold(1Z0-829 / Java SE 17)で狙われるコンパイルエラー系の誤答パターンを、カテゴリ別に、実際のコード例つきで解説します。単なる暗記ではなく「なぜエラーになるのか」「本番でどう見抜くか」まで踏み込みます。
※Java Gold(Oracle Certified Professional: Java SE 17 Developer)の試験範囲・出題形式・受験料・試験時間などの認定制度は改定されることがあります。本記事の制度説明は執筆時点(2026年)の理解にもとづくものです。受験前には必ずOracle認定資格の公式サイト、および試験配信を担う各社(ピアソンVUE等)で最新情報をご確認ください。
- Java Goldでコンパイルエラー系の誤答が頻出する理由と、本番での判定手順
var(型推論)にまつわるコンパイルエラーの誤答パターンfinal・アクセス修飾子・オーバーライドの引っかけ- ジェネリクス・ワイルドカードの型エラーの見抜き方
- switch式・sealed・recordなど新しめの文法の落とし穴
- 例外・try-with-resources・ラムダのコンパイルエラー
- 紛らわしい選択肢を見抜くための実践的なチェック手順
なぜJava Goldはコンパイルエラー系の誤答が多いのか
Java Goldは「実行結果を選ぶ」形式の設問が多く、選択肢に『コンパイルエラー』を混ぜることで、文法の正確な理解を試す構成になっているためです。処理の流れを追う力だけでなく、「そのコードはそもそも成立するのか」を判定する力が同時に問われます。
多くの設問は、次のような選択肢の組み合わせで出されます。
- A. 何らかの値(例:
10)が出力される - B. 別の値(例:
20)が出力される - C. 実行時に例外がスローされる
- D. コンパイルエラーになる
このとき、真面目に処理を追ってAかBで悩んでいると、実は正解がDだった、というのがよくある失点です。処理を追う前に、まず「コンパイルは通るか」を先に判定するのが、Java Goldの鉄則です。
筆者の実感として、Java Goldは「深い設計思想」よりも「文法の細かい正確さ」を執拗に問う試験でした。だからこそ、コンパイルエラーになる条件をパターンとして頭に入れておくと、消去法が一気に速くなります。同じくJava SE系の基礎から積み上げたい方は、資格の全体像を整理したJava資格の取得順序も参考になります。
⚠️ 実務では警告レベルで済む書き方でも、試験では「コンパイルエラー」として問われることがあります。試験は言語仕様に厳密です。IDEが自動修正してくれる書き方こそ、あえて手で書いてエラーを再現しておきましょう。
var(型推論)のコンパイルエラー誤答パターン
varはローカル変数の型推論専用であり、使える場所が厳密に限定されています。フィールド・メソッド引数・戻り値には使えず、初期化子から型が推論できないケースもすべてコンパイルエラーになります。Java Goldで最頻出の引っかけの一つです。
varがコンパイルエラーになる代表的なケースを整理します。
| ケース | 例 | 結果 |
|---|---|---|
| 初期化なし | var x; |
コンパイルエラー |
| null初期化 | var x = null; |
コンパイルエラー(型推論できない) |
| 複数宣言 | var a = 1, b = 2; |
コンパイルエラー |
| 配列初期化子 | var arr = {1, 2, 3}; |
コンパイルエラー |
| ラムダを直接代入 | var f = () -> 42; |
コンパイルエラー(ターゲット型が必要) |
| メソッド参照を直接代入 | var m = String::length; |
コンパイルエラー |
| フィールド宣言 | class C { var x = 1; } |
コンパイルエラー |
| メソッド引数・戻り値 | void m(var x) {} |
コンパイルエラー |
横にスクロールできます
一方で、次のような使い方は正しくコンパイルできるので、これを「エラーだ」と誤答しないよう注意します。
var list = new ArrayList<String>();(右辺から型が明確)- 拡張for文の変数:
for (var s : list) { ... } - try-with-resourcesのリソース変数:
try (var r = open()) { ... } - ラムダの引数での
var:(var a, var b) -> a + b(ただし全引数にvarを付ける・型と混在は不可)
varはとにかく便利だから、どこでも使えると思っていました。varは「ローカル変数で、右辺から型が一意に決まるとき」限定なんだ。フィールドや引数に付いていたら、その時点でコンパイルエラー確定だよ。var f = () -> 42;がダメなのはなぜですか?varだと推論のよりどころがなくて、型が決められないんだ。このように、var絡みの設問は「処理を追うまでもなく、宣言の形だけでエラーが確定する」ことが多い。選択肢にvarが出たら、まず宣言の場所と初期化子を疑うのが定石です。
final・アクセス修飾子・オーバーライドの引っかけ
final変数への再代入、抽象クラスのインスタンス化、抽象メソッドの実装漏れ、オーバーライド時のアクセス修飾子の弱化などは、いずれもコンパイルエラーになる定番パターンです。「実行時に例外」ではなく「コンパイルで止まる」点がポイントです。
finalの再代入
finalが付いた変数・フィールドは一度だけ代入でき、二度目の代入はコンパイルエラーです。ループの中でfinal変数に代入し直すコードなどが引っかけとして出ます。
final int x = 10;
x = 20; // コンパイルエラー:finalへの再代入
抽象クラス・インターフェースのインスタンス化
abstractクラスはnewできません。また、抽象メソッドを実装し切っていない具象クラスもコンパイルエラーになります。
abstract class Animal { abstract void cry(); }
Animal a = new Animal(); // コンパイルエラー:抽象クラスはnew不可
オーバーライドの制約
メソッドをオーバーライドするとき、次に該当するとコンパイルエラーになります。ここは細かく問われます。
- アクセス修飾子を狭める(例:親の
publicを子でprotectedに)→ エラー - チェック例外を新たに増やす/広げる(親がthrowしない例外を子で追加)→ エラー
- 戻り値を非共変な型に変える(共変戻り値=親の戻り型のサブ型ならOK、無関係な型はエラー)
finalメソッドのオーバーライド → エラーstaticメソッドは「オーバーライド」ではなく「隠蔽」になる(インスタンスメソッドで隠蔽しようとすると不整合でエラーになるケースあり)
RuntimeException系(非チェック例外)は増やしても問題ないんだ。ここは頻出だから、チェック/非チェックの区別とセットで押さえておこう。アクセス修飾子とパッケージの関係(privateメンバへの外部アクセス、デフォルトアクセスのパッケージ跨ぎ)も、コンパイルエラーの温床です。「別パッケージからprotectedメンバを継承なしで触ろうとしている」といった設問は、処理ではなくアクセス可否で答えが決まります。
ジェネリクス・ワイルドカードの型エラー
ジェネリクスでは、ワイルドカードの上限・下限の向きを取り違えたコードがコンパイルエラーになります。特に「? extendsのコレクションに要素を追加する」パターンは頻出の引っかけです。
境界ワイルドカードの原則(PECS=Producer Extends, Consumer Super)を、コンパイル可否の観点で整理します。
| 宣言 | 要素の取り出し(read) | 要素の追加(add) |
|---|---|---|
List<? extends Number> |
できる(Numberとして) |
できない(nullを除く)→ addはコンパイルエラー |
List<? super Integer> |
Objectとしてのみ |
Integerとそのサブ型を追加できる |
List<Number> |
できる | Numberとサブ型を追加できる |
横にスクロールできます
List<? extends Number> list = new ArrayList<Integer>();
list.add(1); // コンパイルエラー:? extends には追加できない
Number n = list.get(0); // これはOK(取り出しは可能)
その他、ジェネリクスで狙われるコンパイルエラーのパターンです。
- ジェネリック型のインスタンスをnew時に型引数不一致:
List<String> l = new ArrayList<Integer>();はエラー - プリミティブ型を型引数に使う:
List<int>はエラー(List<Integer>が正しい) - 静的コンテキストで型パラメータを使う:クラスの型パラメータ
Tをstaticメソッド/staticフィールドで使うとエラー - ジェネリック配列の生成:
new T[10]やnew List<String>[10]はエラー
? extendsにaddできないのが、毎回ピンと来ません。List<? extends Number>は「Numberの何らかのサブ型のリスト」で、中身がIntegerのリストかDoubleのリストか特定できないんだ。だから何を入れても型安全を保証できず、コンパイラがaddを禁止する。逆に取り出しはNumberとして安全だから許される、という理屈だよ。ジェネリクスの設問は、パッと見で処理を追いたくなりますが、型の宣言と操作(add/get)の組み合わせだけでエラーが確定することが多い。まず宣言のextends/superの向きを見るのが近道です。
switch式・sealed・recordの落とし穴
Java SE 17で正式化されたswitch式・sealedクラス・recordは、専用の文法制約があり、そこを外すとコンパイルエラーになります。新しめの文法ほど、細かいルール違反が誤答パターンとして狙われます。
switch式(arrow・yield・網羅性)
switch式(->やyieldを使い、値を返す形)には次の制約があります。
- 式として使うときは網羅的でなければならない:enumやsealed型で全ケースを尽くさない、または
defaultが無いとコンパイルエラー yieldは値を返すための予約語的な使い方で、arrow構文(case X -> ...)とcolon構文(case X:)の混在はエラー- arrow構文の
caseではフォールスルー(次のcaseへの落下)が起きない
int x = 2;
String s = switch (x) {
case 1 -> "one";
case 2 -> "two";
// default が無く、intを網羅していない → コンパイルエラー
};
sealedクラス
sealedクラス/インターフェースはpermitsで継承を許可する型を明示し、その許可された型はfinal・sealed・non-sealedのいずれかを必ず宣言しなければなりません。これを付け忘れるとコンパイルエラーです。
sealedなのにpermitsで挙げた型が同一モジュール/パッケージにない → エラー- 許可された子クラスが
final/sealed/non-sealedのどれも付けていない → エラー
record
recordは不変(イミュータブル)が前提の特殊なクラスで、次が制約になります。
- レコードコンポーネント(フィールド)は暗黙に
finalで、再代入しようとするとコンパイルエラー - インスタンスフィールドを新たに追加できない(コンポーネント以外のインスタンス変数は宣言不可)→ エラー
recordは暗黙にfinalで、他クラスをextendsできない
defaultを書かなくても、caseを並べれば動くと思っていました。defaultなしでも通ることはあるけど、値を返すswitch「式」は網羅性が必須なんだ。intのように取り得る値が多い型では、defaultが無いと即コンパイルエラー。enumやsealedで全パターンを書き切った場合だけdefaultを省ける、と覚えておくといいよ。これらは比較的新しい文法なので、古い教材だと手薄になりがちです。Java SE 17の範囲に対応した教材で、実際にjavacに通してエラーを再現するのが確実です。
例外・try-with-resources・ラムダのエラー
チェック例外の握りつぶし、到達不能なcatch、try-with-resourcesのリソース要件、ラムダでのローカル変数キャプチャ(実質的にfinal)も、コンパイルエラーとして頻出します。実行時例外ではなく、コンパイル段階で止まる点を取り違えないことが大切です。
例外まわり
- チェック例外を
try-catchもしくはthrowsで処理していない → コンパイルエラー(未報告例外) - 到達不能なcatch:親例外を先にcatchし、その後でサブ例外をcatchすると「到達不能」でエラー
- マルチキャッチで親子関係の例外を並べる:
catch (IOException | FileNotFoundException e)は親子重複でエラー
try {
// ...
} catch (Exception e) {
// ...
} catch (IOException e) { // コンパイルエラー:到達不能(Exceptionが先に捕捉)
// ...
}
try-with-resources
- リソースは
AutoCloseable(またはCloseable)を実装している必要がある。実装していない型をtry(...)に置くとエラー - try-with-resourcesで外部の変数を参照する場合、その変数はfinalまたは実質的にfinalでなければならない
ラムダのキャプチャ
ラムダ式やローカルクラスがローカル変数を参照するとき、その変数は実質的にfinal(effectively final)である必要があります。ラムダの外でその変数に再代入していると、コンパイルエラーになります。
int count = 0;
Runnable r = () -> System.out.println(count); // ここまではOK
count = 1; // これがあると、上のラムダのcount参照がコンパイルエラーになる
finalって書いていなくても使えますよね?例外・リソース・ラムダは、いずれも「実行してみないと分からない」と思いがちですが、実際にはコンパイル段階で弾かれるものが多い。ここを見分けられると、「実行時例外」という選択肢に惑わされずに済みます。
紛らわしい選択肢を見抜く実践チェック手順
選択肢に「コンパイルエラー」「実行時例外」「何も出力されない」が並ぶときは、処理を追う前に、文法違反を上から順に走査するのが最速です。筆者が本番で使っていた判定手順を、チェックリストの形で共有します。
コードを読むとき、次の順でスキャンします。該当があれば、その時点で「コンパイルエラー」が濃厚です。
- 宣言の形を見る:
varがフィールド/引数/戻り値に付いていないか。var x = null;や複数宣言になっていないか - finalを探す:
final変数・フィールドへ二度目の代入がないか - 型の一致を見る:ジェネリクスの型引数不一致、
? extendsへのadd、プリミティブの型引数 - クラス構造を見る:抽象クラスの
new、実装漏れ、finalメソッドやアクセス修飾子を弱めたオーバーライド - 新文法の制約:switch式の網羅性、sealedの
permitsとfinal/sealed/non-sealed、recordのフィールド再代入 - 例外の整合:未処理のチェック例外、到達不能なcatch、マルチキャッチの親子重複
- キャプチャ:ラムダ/ローカルクラスが参照する変数が実質的finalか
この7点に引っかからなければ、初めて「実行結果」の計算に進みます。順番が逆——先に処理を追ってしまう——と、時間を使ったあげく答えがコンパイルエラーだった、という典型的な失点につながります。
⚠️ ここで挙げたのは「よく出る」パターンであり、すべてを網羅したものではありません。最終的には、実際の問題演習でパターンを体に入れることが必要です。模試で間違えた問題は「なぜコンパイルエラーになるのか」を一言で説明できるまで戻して復習しましょう。
こうしたコンパイル可否の判定力は、実務でのコードレビューにも直結します。資格を実務や市場価値にどうつなげるかという観点では、エンジニアのスキルアップ・ロードマップやJava資格の取得順序もあわせて読むと、Java Goldの位置づけが立体的に見えてきます。
Java Gold 誤答パターン・コンパイルエラーのよくある質問(FAQ)
Java Gold(1Z0-829)でコンパイルエラー系の誤答パターンが多いのはなぜですか?
var・final・ジェネリクス・アクセス修飾子などの文法違反を仕込んだ引っかけが頻出します。実行結果を計算する前に、コンパイル可否のチェックを先に行うのが定石です。Java Gold で var を使ったコードの誤答パターンにはどんなものがありますか?
varはローカル変数の型推論専用のため、フィールド・メソッド引数・戻り値の型には使えず、これらに使うとコンパイルエラーになります。またvar x = null;のように初期化子から型が推論できない場合、初期化なしのvar x;、1行での複数宣言var a = 1, b = 2;、配列初期化子var arr = {1,2};、ラムダの左辺var f = () -> {};もすべてコンパイルエラーです。これらは頻出の引っかけです。Java Gold の紛らわしい選択肢を見抜くコツはありますか?
final変数の再代入、抽象クラスのインスタンス化、実装漏れ、チェック例外の握りつぶし、到達不能なcatch、ジェネリクスの型不一致など、コンパイルを止める典型パターンを先に潰すと、実行結果の計算に進むべきか、その時点で答えが決まるかを素早く判断できます。Java Gold のコンパイルエラー系対策は独学でもできますか?
コンパイルエラーと実行時例外は、選択肢でどう見分ければいいですか?
NullPointerExceptionやArrayIndexOutOfBoundsExceptionなど)は、文法上は正しいコードが実行中に落ちるものです。見分け方の基本は「そもそもコンパイルが通るか」を先に判定すること。文法・型が正しければ、次に実行時の値(nullや範囲外アクセス)を追って例外の有無を判断します。Java Gold は暗記だけで合格できますか?
まとめ:Java Gold コンパイルエラー系の誤答パターンと見抜き方
Java Gold(1Z0-829 / Java SE 17)のコンパイルエラー系の誤答パターンを整理します。
- 前提:Java Goldは「実行結果を選ぶ」設問が多く、選択肢に必ず『コンパイルエラー』が混ざる。処理を追う前にコンパイル可否を先に判定するのが鉄則
- var:フィールド・引数・戻り値には使えない。
null初期化・複数宣言・初期化なし・配列初期化子・ラムダ直接代入はすべてコンパイルエラー - final・オーバーライド:
finalの再代入、抽象クラスのnew、実装漏れ、アクセス修飾子の弱化、チェック例外の追加はエラー - ジェネリクス:
? extendsへのaddは不可、型引数不一致・プリミティブ型引数・静的コンテキストでの型パラメータはエラー - 新文法:switch式の網羅性、sealedの
permitsと修飾子、recordのフィールド再代入・拡張の制約 - 例外・ラムダ:未処理のチェック例外、到達不能catch、
AutoCloseableでないリソース、実質的finalでない変数のキャプチャはエラー - 本番の手順:宣言→final→型→クラス構造→新文法→例外→キャプチャの順に走査し、引っかからなければ実行結果の計算に進む
コンパイルエラー系は、パターンさえ押さえれば「処理を追わずに答えが決まる」おいしい問題群です。模試で間違えたコードは、なぜエラーになるのかを一言で説明できるまで戻し、javacやIDEで実際に再現しておきましょう。
Javaの資格を「どの順で取り、実務とどうつなげるか」という全体像を描きたい方はJava資格の取得順序、市場価値の高め方はエンジニアのスキルアップ・ロードマップもあわせてどうぞ。
免責:本記事は筆者の実体験および執筆時点で一般に公開されている情報にもとづく情報提供であり、特定の合格・成果を保証するものではありません。掲載しているコード例・文法の挙動は、Java SE 17を前提とした一般的な理解にもとづくものであり、実際の挙動は実行環境やバージョンによって異なる場合があります。Java Gold(Oracle Certified Professional: Java SE 17 Developer / 1Z0-829)の試験範囲・出題形式・受験料・試験時間などの認定制度は改定されることがあります。受験前には必ずOracle認定資格の公式サイトおよび試験配信各社の最新情報をご確認ください。最終的な判断はご自身の責任で行ってください。
