Javaの配列の宣言・代入ルール
- 宣言と初期化子の代入は同時に行う必要がある
- サイズ指定と初期化子の併用は不可
- 代入のみの場合は new 型[]{...} を使う
- [] の位置は型の後でも変数名の後でもOK
① 宣言のみ(メモリ確保なし)
int[] a;
int a[];
配列変数を宣言するだけ。まだメモリは確保されていない。
[] は型の後でも変数名の後でもOK。
② 宣言とメモリ確保(サイズ指定)
int[] a = new int[3];
int a[] = new int[3];
要素数3のint型配列を作成。
初期値は型に応じたデフォルト値(intなら0)。
③ 宣言と初期化(初期化子を使う)
int[] a = {1, 2, 3};
int a[] = {1, 2, 3};
宣言と同時に初期化子で値を代入。
サイズは初期化子の要素数から自動推論。
④ 宣言と代入を分ける(初期化子を使う場合)
int[] a;
a = new int[]{1, 2, 3}; // OK
new int[]{...} の形であれば、宣言と代入を分けてもOK。
a = {1, 2, 3}; はエラーになる。
⑤ 要素ごとの代入
int[] a = new int[3];
a[0] = 10;
a[1] = 20;
a[2] = 30;
配列の各要素に個別に値を代入。
よくあるエラー例と理由
| 書き方 | 結果 | 理由 |
|---|---|---|
| int[] a = new int[3]{1,2,3}; | ❌ エラー | サイズ指定と初期化子の併用は禁止 |
| int[] a; a = {1,2,3}; | ❌ エラー | 初期化子のみの代入は宣言と同時でないと不可 |
| int[] a = new int[]; | ❌ エラー | 要素数または初期化子が必要 |
Javaの static メンバー ルール
Javaの static メンバーは「クラスに属する共有資源」であり、インスタンスを介さずにアクセスできます。主なルールは以下の通りです。
Javaの static メンバーの基本ルール一覧
1. static 変数(静的フィールド)
- クラス全体で1つだけ存在し、すべてのインスタンスで共有される。
- インスタンスを生成しなくても クラス名.変数名 でアクセス可能。
- 初期化は1回だけ(クラスロード時)。static final を使えば 定数として扱える。
2. static メソッド(静的メソッド)
- インスタンス化せずに クラス名.メソッド名() で呼び出せる。
- インスタンス変数やインスタンスメソッドには直接アクセスできない。
例:static メソッド内で this は使えない。
代表例:main() メソッド、ユーティリティクラスのメソッド。
3. static ブロック(静的初期化ブロック)
- クラスがロードされたときに 一度だけ実行される初期化コード。
- 複雑な初期化処理に使える。
static {
// 初期化処理
}
4. static インナークラス(静的内部クラス)
- 外部クラスのインスタンスなしで使える内部クラス。
- 外部クラスの非staticメンバーにはアクセスできない。
class Outer {
static class Inner {
// 外部クラスのインスタンス不要
}
}
5. static import(静的インポート)
- 他クラスの static メンバーを クラス名なしで使用可能にする。
import static java.lang.Math.PI;
System.out.println(PI); // クラス名なしで使える
注意点と制約
- インスタンスメンバーにはアクセス不可(staticメソッドやブロック内)
- マルチスレッド環境では競合に注意(共有されるため)
- オブジェクト指向の原則とバランスが重要:staticの使いすぎは設計を壊す可能性あり
使い分けの目安
| 用途 | static を使うべきか? |
|---|---|
| クラス全体で共有したい値 | ✅ 使う(例:カウンター) |
| ユーティリティ処理 | ✅ 使う(例:Mathクラス) |
| インスタンスごとの状態管理 | ❌ 使わない(インスタンス変数) |
| 複雑な初期化処理 | ✅ staticブロックが有効 |
Java 可変長引数(varargs)ルール完全まとめ表
| 項目 | 内容 | 補足・例 |
|---|---|---|
| 基本構文 | メソッド名(型... 引数名) |
void printAll(String... items)呼び出し側: printAll("A", "B", "C")
|
| 内部的な扱い | 配列として扱われる |
String... は String[] と同等。ループ処理なども配列と同様に可能 |
| 引数の個数 | 0個以上渡せる |
printAll() のように引数なしでも呼び出し可能(空配列として扱われる) |
| 位置制限 | メソッド引数の最後にのみ使用可能 |
void method(int x, String... args) → OKvoid method(String... args, int x) → ❌ コンパイルエラー |
| 複数定義不可 | varargs は1メソッドにつき1つのみ |
void method(int... a, String... b) → ❌ コンパイルエラー |
| 型の統一 | varargs の型は1種類のみ |
void method(int... nums) → OKvoid method(int... a, String... b) → ❌(複数定義+異なる型) |
| オーバーロードとの関係 | 配列とのオーバーロードに注意 |
void method(String[] args) と void method(String... args) は同一扱いで競合する可能性あり |
| null の扱い |
null を渡すと配列自体が null
|
method(null) → args == null(NullPointerException に注意) |
| 空配列の扱い | 引数なし → 空配列として渡される | args.length == 0 |
| 配列として渡す | 明示的に配列を渡すことも可能 | method(new String[]{"a", "b"}) |
| ジェネリクスとの併用 | 非推奨(ヒープ汚染の可能性) |
@SafeVarargs アノテーションで警告を抑制可能(static メソッドや final メソッドに限る) |
| 可読性の注意点 | 引数が多いと可読性が低下する | 過剰な varargs 使用は避け、必要に応じてビルダーパターン等を検討 |
| 可変長引数の配列化 | varargs は内部的に配列に変換される |
method("a", "b", "c") → String[] args = {"a", "b", "c"}
|
| 配列と varargs の違い | 呼び出し時の構文が異なる |
method("a", "b")(varargs) vs method(new String[]{"a", "b"})(配列) |
| リフレクションとの関係 |
Method#getParameterTypes() は配列型を返す |
String... → Class<?>[] では String[].class として取得される |
よくあるコンパイルエラー例
| コード例 | エラー理由 |
|---|---|
void test(int... a, String... b) |
複数の varargs 定義は不可 |
void test(String... a, int b) |
varargs は最後の引数でなければならない |
void test(String... a, String... b) |
同じ型でも複数の varargs は不可 |
Java オーバーロードの条件まとめ表
| 条件 | 内容 | 例 | 備考 |
|---|---|---|---|
| シグネチャが異なること | シグネチャ(メソッド名+引数の型と順序)が異なればオーバーロード可能 | print(int) / print(double) / print(int, String) | ✅ オーバーロードの本質的条件 |
| メソッド名が同じであること | オーバーロード対象のメソッドはすべて同じ名前でなければならない | print(String s) / print(int i) | ✅ 必須条件 |
| 引数の個数が異なること | 引数の数が違えばオーバーロード可能 | print(String s) / print(String s, int i) | ✅ 有効 |
| 引数の型が異なること | 同じ個数でも型が違えばオーバーロード可能 | print(int i) / print(double d) | ✅ 有効 |
| 引数の並び順が異なること | 型が同じでも順番が違えばオーバーロード可能 | print(String s, int i) / print(int i, String s) | ✅ 有効 |
| 戻り値の型は関係ない | 戻り値の型が違うだけではオーバーロードできない | public print(int i) / private print(int i) | ❌ 無効(同じシグネチャ) |
| アクセス修飾子は関係ない | public/private などの違いはオーバーロードに影響しない | public print(int i) / private print(int i) | ❌ 無効(同じシグネチャ |
| 例外の有無は関係ない | throws の有無や種類はオーバーロードに影響しな | print(int i) / print(int i) throws IOException | ❌ 無効(同じシグネチャ) |
| 可変長引数との組み合わせに注意 | int... は int[] と同じ扱いになるため、曖昧な定義に注意 | print(int... nums) / print(int[] nums) | ❌ 無効(同じ扱い) |
Java コンストラクタのルールまとめ表【完全版】
| 項目 | 内容 | 備考・例 |
|---|---|---|
| 名前はクラス名と同じ | コンストラクタの名前はクラス名と完全に一致する必要がある | class Car { Car() { } } |
| 戻り値を持たない | 戻り値(void含む)を指定してはいけない | Car() { } ← OK / void Car() { } ← NG(メソッド扱い) |
| デフォルトコンストラクタ | コンストラクタを定義しない場合、引数なしのコンストラクタが自動生成される | class Car { } → new Car() はOK |
| 明示定義でデフォルト消失 | コンストラクタを1つでも定義すると、デフォルトコンストラクタは自動生成されない | Car(String name) {} のみ → new Car() はNG |
| オーバーロード可能 | 引数の数や型が異なれば複数定義できる | Car() / Car(String name) / Car(String name, int year) |
| this() で他のコンストラクタ呼出し | 同じクラス内の別のコンストラクタを呼び出す | this("default", 2020); |
| this() は先頭のみ使用可能 | コンストラクタの先頭でのみ使用可能 | Car() { this("default"); } ← OK / Car() { println(); this("default"); } ← NG |
| super() で親クラスの呼び出し | 明示しない場合は暗黙的に super() が呼ばれる | super("parent"); |
| super() も先頭のみ使用可能 | this() と同様、1行目に書く必要がある | Car() { super(); } ← OK |
| this() と super() は併用不可 | 両方を同時に使うことはできない | どちらか一方のみ使用可能 |
| アクセス修飾子を指定できる | public, protected, private などでアクセス制御可能 | private Car() → シングルトンなどで使用 |
| 抽象クラスにも定義可能 | 抽象クラスでも初期化処理を記述できる | abstract class Animal { Animal(String name) { ... } } |
| インターフェースには定義不可 | インターフェースはインスタンス化されないため | interface A { A() { } } ← NG(コンパイルエラー) |
補足:コンストラクタとメソッドの違い
| 比較項目 | コンストラクタ | メソッド |
|---|---|---|
| 名前 | クラス名と完全一致 | 任意の名前 |
| 戻り値 | なし(void も不可) |
任意の戻り値型(void, int, String など) |
| 呼び出し方法 | インスタンス生成時に自動的に呼び出される | 明示的に呼び出す必要がある(例:obj.method()) |
| 定義目的 | オブジェクトの初期化処理 | 任意の処理(計算、表示、操作など) |
| オーバーロード | 可能(引数の違いで複数定義できる) | 可能(同様に引数の違いで複数定義できる) |
| 継承との関係 | インターフェースでは定義不可、抽象クラスでは定義可能 | インターフェースでも抽象クラスでも定義可能 |
| アクセス修飾子 | 使用可能(public, private, protected など) |
使用可能(同様にアクセス制御できる) |
| 特殊呼び出し |
this() や super() で他のコンストラクタを呼び出せる |
this や super で親クラスのメソッドを呼び出せる |
【図解】インスタンス生成時の初期化の流れ
new クラス名(); を呼び出すと…
┌────────────────────────────────────────────┐
│ ① 親クラスの初期化 │
│ - 親クラスのフィールド初期化 │
│ - 親クラスの初期化ブロック({}) │
│ - 親クラスのコンストラクタ │
└────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────┐
│ ② 子クラスのフィールド初期化 │
│ - 例:int x = 10; │
└────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────┐
│ ③ 子クラスのインスタンス初期化ブロック │
│ - 例:{ System.out.println("Bstr"); } │
└────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────┐
│ ④ 子クラスのコンストラクタ実行 │
│ - 例:Car() { System.out.println("Astr"); } │
└────────────────────────────────────────────┘
class Parent {
int a = initA(); // フィールド初期化
{
System.out.println("Parent instance block"); // 初期化ブロック
}
Parent() {
System.out.println("Parent constructor");
}
int initA() {
System.out.println("Parent field init");
return 1;
}
}
class Child extends Parent {
int b = initB(); // フィールド初期化
{
System.out.println("Child instance block"); // 初期化ブロック
}
Child() {
System.out.println("Child constructor");
}
int initB() {
System.out.println("Child field init");
return 2;
}
}
public class Main {
public static void main(String[] args) {
new Child();
}
}
Java アクセス修飾子の種類とアクセス範囲一覧
| 修飾子 | 同一クラス内 | 同一パッケージ内 | サブクラス(別パッケージ) | その他のクラス | 主な用途とルール |
|---|---|---|---|---|---|
public |
○ | ○ | ○ | ○ | どこからでもアクセス可能。API公開用のメソッドやクラスに使用。 |
protected |
○ | ○ | ○ | × | 継承関係にあるクラスや同一パッケージ内からアクセス可能。 |
| (指定なし) ※パッケージプライベート |
○ | ○ | × | × | 修飾子を付けない場合。パッケージ内でのみアクセス可能。 |
private |
○ | × | × | × | 自クラス内のみアクセス可能。カプセル化の基本。 |
よくある誤解
- クラスが public でも、メンバーのアクセスには別のルールがある
- クラスがpublicでも、その中の変数やメソッド全部はアクセスできない
public class Parent {
int num = 100; // ← これは default(パッケージプライベート)
}
この場合、Parent クラスは他パッケージから使えますが、num にはアクセスできません。
理由
- num は default アクセス → 同じパッケージ内からしかアクセスできない
- 他パッケージの Child クラスからは見えない
抽象クラスの基本ルール
abstract キーワードを使って定義する
abstract class Animal {
abstract void makeSound(); // 抽象メソッド
void sleep() { System.out.println("Zzz..."); } // 具象メソッド
}
Java 抽象クラス(abstract class)のルール
■ インスタンス化できない
- 抽象クラスは new で直接インスタンス化できません。
■ 抽象メソッドを1つ以上含むことができる
- 抽象メソッドとは、本体(中身)のないメソッドで、サブクラスでの実装が必須です。
■ 抽象メソッドがある場合、そのクラスも抽象クラスでなければならない
- 抽象メソッドを含むクラスには abstract 修飾子が必須です。
■ 具象メソッド(中身のあるメソッド)も定義可能
- 共通処理を抽象クラス内で実装し、サブクラスで使い回すことができます。
■ フィールドやコンストラクタも定義可能
- 通常のクラスと同様に、フィールドやコンストラクタを持つことができます。
■ 継承したサブクラスは、すべての抽象メソッドをオーバーライドしなければならない
- ただし、サブクラスも抽象クラスであれば未実装のままでもOKです。
■ final 修飾子と併用できない
- abstractは「継承されること」を前提とするため、
final(継承禁止)とは両立できません。
■ static メソッドは抽象にできない
- 抽象メソッドはインスタンスに依存するため、
staticとの併用は不可です。
Java 抽象クラスのルールチェックリスト
| 項目 | 内容 | 備考 |
|---|---|---|
abstract キーワード |
クラス定義に必須 | abstract class クラス名 |
| インスタンス化不可 |
new で直接生成できない |
サブクラス経由で使用 |
| 抽象メソッドの定義 | 本体なし・サブクラスで実装必須 | abstract void メソッド名(); |
| 抽象メソッドを含む場合 | クラスも抽象化が必要 | 抽象メソッドが1つでもあれば必須 |
| 具象メソッドの定義可 | 共通処理を実装可能 | 継承先でそのまま利用可 |
| フィールド・コンストラクタ定義可 | 状態保持や初期化処理が可能 | インターフェースとの違い |
| サブクラスの義務 | 抽象メソッドの実装が必須 | 未実装ならサブクラスも抽象化 |
final との併用不可 |
継承禁止と矛盾するため | コンパイルエラーになる |
static 抽象メソッド不可 |
インスタンスに依存するため |
static abstract は不可 |
| アクセス修飾子 |
public, protected, default 可 |
private は不可(継承できない) |
interface インターフェイス
目的「クラスに“必ず実装すべきメソッド”を定義する契約書」
特徴(Java 8 以降)
すべてのメソッドは public(省略可)
抽象メソッド(abstract)は書かなくても abstract 扱い
- default メソッド(中身あり)も書ける
- static メソッドも書ける
- フィールドは public static final(定数)しか持てない
- コンストラクタは持てない
- 多重実装が可能(クラスは1つしか継承できないが、interfaceは複数OK)
イメージ図
[Runnable] interface
└─ run()(抽象メソッド)
abstract classとinterface比較表
| 項目 | abstract class | interface |
|---|---|---|
| 目的 | 共通処理+未完成部分をまとめる 実装すべきメソッドの契約 | |
| インスタンス化 | ❌ できない | ❌ できない |
| フィールド | ◯ 持てる | △ 定数のみ(public static final) |
| 具体メソッド | ◯ 書ける | ◯ default / static は書ける |
| 抽象メソッド | ◯ 書ける | ◯ 書ける(abstract 省略可) |
| コンストラクタ | ◯ 持てる | ❌ 持てない |
| 多重継承 | ❌ 不可 | ◯ 可能 |
| 用途 | “共通の性質”をまとめる | “必ず実装すべき機能”を定義 |
コードで比較
抽象クラス
abstract class Animal {
String name;
Animal(String name) {
this.name = name;
}
abstract void cry();
void sleep() {
System.out.println("zzz...");
}
}
インターフェイス
interface Movable {
void move(); // 抽象メソッド(abstract省略)
default void stop() {
System.out.println("Stopped");
}
}
実装側
class Dog extends Animal implements Movable {
Dog(String name) {
super(name);
}
@Override
void cry() {
System.out.println("ワン!");
}
@Override
public void move() {
System.out.println("走る!");
}
}
試験でよく出る“ひっかけポイント”
- interface のフィールドは public static final のみ(省略してもそうなる)
- interface のメソッドは public でなければならない(省略しても public)
- abstract class は コンストラクタを持てる
- interface は コンストラクタを持てない
- クラスは 1つしか継承できないが、interface は 複数実装できる
- default メソッドは Object のメソッド(toString など)を override できない
オーバーライドの成立条件
1. メソッド名
- 親クラスと完全に同じ名前であること
2. 引数の型・数・順序
- 完全一致していること(オーバーロードと区別)
3. 戻り値の型
- 親クラスと同じ型、またはそのサブクラス(共変戻り値)
4. アクセス修飾子
- 親クラスより「同じか広い」アクセスレベルであること
- 例:
protected→publicはOK、public→protectedはNG
- 例:
5. throws句(例外宣言)
- 親クラスより「同じか狭い」例外クラスのみ指定可能
- 例:親が
IOException→ 子はIOExceptionまたはそのサブクラス
- 例:親が
6. static メソッド
-
staticメソッドはオーバーライド不可(定義すると「隠蔽」になる)
7. final メソッド
-
finalが付いたメソッドはオーバーライド不可
8. private メソッド
- 親クラスのメソッドが
privateでないこと-
privateメソッドは継承されないため、オーバーライド不可
-
9. @Override アノテーション
- 任意だが、付けることでコンパイル時にオーバーライドの正当性をチェックできる
10. abstract メソッドの実装
- 抽象メソッドはサブクラスで必ずオーバーライドする必要がある
🔐 アクセス修飾子ごとのオーバーライド可否
| 親クラスの修飾子 | 子クラスから見える? | オーバーライド可能? | 備考 |
|---|---|---|---|
public |
✅ 見える | ✅ 可能 | 最も自由にオーバーライドできる |
protected |
✅ 見える | ✅ 可能 | 同一パッケージ or 継承関係でアクセス可能 |
| (なし) | ✅ パッケージ内のみ | ✅ 可能(同パッケージ) | デフォルトアクセス。別パッケージでは不可 |
private |
❌ 見えない | ❌ 不可能 | 子クラスからはアクセス不可。別メソッド扱い |
🧪 呼び出し例と動作確認
class Parent {
private void greet() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
public void greet() {
System.out.println("Hello from Child");
}
}
Parent p = new Child();
p.greet(); // ❌ コンパイルエラー(Parentにpublic greet()がない)
Child c = new Child();
c.greet(); // ✅ 呼び出し可能(Childのgreet())
Java メソッドの再定義:オーバーライド vs オーバーロード
| 用語 | 意味 | アクセス修飾子の影響 |
|---|---|---|
| オーバーライド | 親クラスのメソッドを再定義 |
private は不可(見えない) |
| オーバーロード | 同じ名前で引数が異なるメソッドを複数定義 | アクセス修飾子は関係なし |
共変型(Covariant Return Type)とは?
オーバーライド時に「戻り値の型が親クラスと同じでなくても、そのサブクラスならOK」というルールが導入されました。これが共変型です。
Animal → Cat
class Animal {
public String getName() { return "Animal"; }
}
class Cat extends Animal {
@Override
public String getName() { return "Cat"; }
}
class Parent {
public Animal getAnimal() {
return new Animal();
}
}
class Child extends Parent {
@Override
public Cat getAnimal() { // ✅ 共変型:Animal → Cat
return new Cat();
}
}
Parent.getAnimal() の戻り値は Animal
Child.getAnimal() の戻り値は Cat(Animalのサブクラス)
オーバーライド成立
注意点
- プリミティブ型(int, booleanなど)では使えない
- 戻り値がサブクラスでないとエラー
- ジェネリクスとは別の話(ジェネリクスは非変性)
Java 異常動作の比較
① nullが表示されるケース(実行は成功するが期待通りの値が出ない)
発生タイミング:実行時(正常終了)
主な原因:
- フィールド(インスタンス変数)が初期化されていない
- 親クラスと子クラスで同名フィールドが存在し、シャドウされている
- toString()がnullを返す
コード例:
class A {
String name;
void print() {
System.out.println(name); // → nullが表示される
}
}
備考
- フィールドは自動的に初期化される(参照型はnull、数値型は0など)
- ローカル変数ではこの動作は起こらない(次項参照)
② コンパイルエラーになるケース(コードが間違っていて実行できない)
発生タイミング:コンパイル時
主な原因
- ローカル変数が初期化されていない
- 存在しないメソッドやコンストラクタの呼び出し
- 型不一致(例:int x = "abc";)
- アクセス修飾子違反(例:privateメソッドへの外部アクセス)
- 抽象メソッドの未実装
コード例:
void test() {
String name;
System.out.println(name); // → コンパイルエラー(ローカル変数未初期化)
}
Sample s = new Sample(10); // → Sample(int) が定義されていない
備考:
- ローカル変数は明示的な初期化が必要
- IDEやjavacで即座に検出される
③ 実行時に例外がスローされるケース(コンパイルは通るが実行中にクラッシュ)
発生タイミング:実行時
主な原因:
- null参照でメソッドを呼び出す → NullPointerException
- 配列の範囲外アクセス → ArrayIndexOutOfBoundsException
- 型キャスト失敗 → ClassCastException
- ファイル・ネットワーク・DBの読み込み失敗 → IOException など
コード例:
String s = null;
s.length(); // → NullPointerException
int[] a = new int[2];
a[5] = 10; // → ArrayIndexOutOfBoundsException
Object o = new String();
Integer i = (Integer)o; // → ClassCastException
備考:
- コンパイルは通るが、実行中にクラッシュ
- スタックトレースで原因を特定可能
🧩 Javaモジュールシステムの基礎内容(全体)
🔍 概要
- Java 9から導入されたJPMS(Java Platform Module System)
- クラスパスの複雑さを解消し、依存関係を明示的に管理
- セキュリティ、保守性、起動速度、メモリ効率の向上に貢献
##📦 モジュールとパッケージの違い
-
パッケージ:クラスの集合体
-
モジュール:複数のパッケージをまとめた単位で、アクセス制御や依存関係を管理
📝 module-info.java(モジュール定義ファイル)
- モジュールの定義は module-info.java に記述
- モジュールごとに1つだけ存在
基本構文:
module モジュール名 {
requires モジュール名;
exports パッケージ名;
}
主なディレクティブ:
- requires:依存モジュールの指定
- exports:外部に公開するパッケージ
- opens:リフレクション用に公開
- uses:サービス利用の宣言
- provides ... with ...:サービス提供の宣言
🧠 モジュールの命名と構成
- モジュール名は一意である必要がある
- モジュールフォルダは mods などで統一するのが一般的
🔗 モジュール間の依存関係
- requires で依存関係を明示
- requires transitive:依存先の依存も継承
requires static:コンパイル時のみ依存
🚀 自動モジュールと未対応ライブラリ
- JARファイルをモジュールパスに置くと自動モジュールとして扱われる
- モジュール化されていないライブラリとの共存には注意
🛠 モジュールパスとルートモジュール
- --module-path でモジュールの配置場所を指定
- -m モジュール名/メインクラス で起動
✅ モジュール化の利点
- パッケージ単位での情報隠蔽が可能
- 実行時の依存関係チェックにより安定性向上
- 必要なモジュールのみロードすることでリソース効率化
📁 module-info.java の記述場所
- 各モジュールのルートディレクトリ直下に配置
例:src/com.example.myapp/module-info.java
📝 module-info.java の記述例
module com.example.myapp {
requires java.sql;
exports com.example.myapp;
}
📦 ディレクトリ構成例
project/
├── src/
│ └── com.example.myapp/
│ ├── module-info.java
│ └── com/example/myapp/Main.java
└── out/
🔧 コンパイルコマンド
javac -d out --module-source-path src $(find src -name "*.java")
▶️ 実行コマンド
java --module-path out -m com.example.myapp/com.example.myapp.Main
🧱 Java コンパイルエラー一覧表
Javaで発生する代表的なコンパイルエラーをカテゴリ別に整理した一覧です。
🔤 構文エラー(Syntax Errors)
| 原因 | 例 | エラー内容 |
|---|---|---|
| セミコロンの抜け | System.out.println("Hello") |
';' expected |
| 不正な構文 | if (x > 0) int y = 5; |
illegal start of type |
| 括弧の不一致 | if (x > 0 { |
')' expected |
🧬 型不一致(Type Mismatch)
| 原因 | 例 | エラー内容 |
|---|---|---|
| 型が合わない代入 | int x = "abc"; |
incompatible types: String cannot be converted to int |
| メソッドの戻り値型が不一致 |
String s = getNumber();(戻り値がint) |
incompatible types |
| ジェネリクス型不一致 | List<Integer> list = new ArrayList<String>(); |
incompatible types |
📦 未定義の識別子(Undefined Symbols)
| 原因 | 例 | エラー内容 |
|---|---|---|
| 宣言していない変数やメソッド | System.out.println(value); |
cannot find symbol |
| import不足 | List<String> list = new ArrayList<>(); |
cannot find symbol: class List |
🔐 アクセス違反(Access Violations)
| 原因 | 例 | エラー内容 |
|---|---|---|
| privateメンバへのアクセス | obj.privateField = 10; |
has private access |
| privateクラスの外部使用 | new PrivateClass(); |
PrivateClass is not public in package |
🧠 ローカル変数未初期化
| 原因 | 例 | エラー内容 |
|---|---|---|
| 初期化していないローカル変数を使用 | int x; System.out.println(x); |
variable x might not have been initialized |
🧱 クラス・ファイル名不一致
| 原因 | 例 | エラー内容 |
|---|---|---|
| publicクラス名とファイル名が違う |
public class Hello {} in Main.java
|
class Hello is public, should be declared in a file named Hello.java |
⚙️ static/非static混同
| 原因 | 例 | エラー内容 |
|---|---|---|
| staticメソッドから非staticメンバ参照 |
System.out.println(name); in main()
|
non-static variable name cannot be referenced from a static context |
| static文脈でthis使用 |
this.name = "Hiro"; in static |
non-static variable this cannot be referenced from a static context |
🧩 継承・インターフェース関連
| 原因 | 例 | エラー内容 |
|---|---|---|
| 抽象メソッド未実装 | class MyClass implements Runnable {} |
does not override abstract method run() |
| インターフェースのインスタンス化 | new Runnable(); |
Runnable is abstract; cannot be instantiated |
| enumの継承 | enum MyEnum extends OtherEnum {} |
cannot inherit from enum |
インターフェースの特徴
インターフェースとは「クラスが必ず持つべきメソッドの約束(契約)」を定義する仕組みです。
具体的な処理は書かず、メソッドの名前・引数・戻り値だけを決めることで、複数のクラスを同じルールで扱えるようになります。
-
抽象メソッドの集合
→ 処理は書かず「こういうメソッドを持ちなさい」と定義する。 -
複数実装可能
→ クラスは1つの親クラスしか継承できませんが、インターフェースは複数同時に実装できます。 -
疎結合を実現
→ クラス同士を直接結びつけず、インターフェースを介すことで柔軟な設計が可能。 -
Java 8以降の進化
→ default メソッド:インターフェースに処理付きメソッドを定義できる
→ static メソッド:インターフェースに静的メソッドを持たせられる。
身近な例で理解
インターフェースは「リモコンのボタン配置」に例えられます。
- どのテレビにも「電源ボタン」「音量ボタン」がある(=インターフェースで定義)。
- ボタンを押したときの内部処理はメーカーごとに違う(=クラスごとの実装)。
つまり、操作の統一性を保証しつつ、内部の仕組みは自由に変えられるのがインターフェースです。
まとめ
- インターフェースは 「契約」や「設計図」 の役割を持つ。
- クラス間の共通ルールを定義し、ポリモーフィズム(多態性) を実現する。
- 複数実装可能なので柔軟な設計ができる。
- Java 8以降は default や static メソッドでさらに便利になった。
interface Animal {
void speak(); // 抽象メソッド(処理は書かない)
}
class Dog implements Animal {
public void speak() {
System.out.println("ワンワン");
}
}
class Cat implements Animal {
public void speak() {
System.out.println("ニャー");
}
}
Animal a = new Dog();
a.speak(); // 「ワンワン」と出力
ここで重要なのは、Dog と Cat が同じ Animal インターフェースを実装しているため、共通の型として扱えることです。
🧯 例外未処理(Unchecked Exceptions)
| 原因 | 例 | エラー内容 |
|---|---|---|
| チェック例外を処理していない | Thread.sleep(1000); |
unreported exception InterruptedException |
🔁 制御構文の誤用
| 原因 | 例 | エラー内容 |
|---|---|---|
| break/continueの誤用 |
break; outside loop |
break outside switch or loop |
| switch文で変数使用 |
case x:(xが変数) |
constant expression required |
🧮 return文の不足
| 原因 | 例 | エラー内容 |
|---|---|---|
| 戻り値が必要なメソッドでreturnなし | int getValue() {} |
missing return statement |
🧪 その他のエラー
| 原因 | 例 | エラー内容 |
|---|---|---|
| コンストラクタ呼び出しミス | new StringBuilder(1, 2); |
constructor not found |
| 識別子の重複 | int x = 1; int x = 2; |
variable x is already defined |
| 予約語の使用 | int class = 5; |
'class' is a keyword |
| varの誤用(Java 10以降) | var x; |
cannot infer type for local variable |
| ラベルの誤用 | goto: |
undefined label |
🧠 Javaの予約語一覧(全50語)
| キーワード | 説明(簡易) |
|---|---|
| abstract | 抽象クラスやメソッドの定義 |
| assert | 条件チェック(Java 1.4以降) |
| boolean | 真偽値型 |
| break | ループやswitchからの脱出 |
| byte | 8ビット整数型 |
| case | switch文の分岐 |
| catch | 例外処理の捕捉 |
| char | 16ビット文字型 |
| class | クラス定義 |
| const | 予約済み(未使用) |
| continue | ループの次の反復へ |
| default | switch文のデフォルト分岐 |
| do | do-whileループの開始 |
| double | 倍精度浮動小数点型 |
| else | 条件分岐のelse句 |
| enum | 列挙型(Java 5以降) |
| extends | クラスの継承 |
| final | 上書き不可の定義 |
| finally | 例外処理の終了ブロック |
| float | 単精度浮動小数点型 |
| for | forループ |
| goto | 予約済み(未使用) |
| if | 条件分岐 |
| implements | インターフェースの実装 |
| import | クラスの読み込み |
| instanceof | 型判定 |
| int | 32ビット整数型 |
| interface | インターフェース定義 |
| long | 64ビット整数型 |
| native | ネイティブメソッド定義 |
| new | オブジェクトの生成 |
| null | null参照 |
| package | パッケージ定義 |
| private | 非公開アクセス修飾子 |
| protected | 限定公開アクセス修飾子 |
| public | 公開アクセス修飾子 |
| return | メソッドからの戻り値 |
| short | 16ビット整数型 |
| static | 静的メンバー定義 |
| strictfp | 浮動小数点の精度制御 |
| super | 親クラスの参照 |
| switch | 条件分岐 |
| synchronized | 同期制御 |
| this | 自身のインスタンス参照 |
| throw | 例外の送出 |
| throws | 例外の宣言 |
| transient | シリアライズ対象外 |
| try | 例外処理の開始 |
| void | 戻り値なしのメソッド定義 |
| volatile | 変数の同時アクセス制御 |
| while | whileループ |
シグネチャ(Signature)
メソッドを一意に識別するための「名前」「引数の型」「引数の数」「引数の順序」の組み合わせのこと
- 構成要素:
- メソッド名 (例: printData)
- 引数の数
- 引数の型
- 引数の順序 (例: (int, String) と (String, int) は異なる)
メソッド定義
Java のメソッドは4つのパーツでできている。
[修飾子] [戻り値の型] [メソッド名] ( [引数] ) {
// メソッドの処理(本体)
}
- 構成要素(4つのパーツ)
- 修飾子(modifier)
- 戻り値の型(return type)
- メソッド名(method name)
- 引数(parameter)
【参考文献】
https://www.furikatu.com/2025/08/java-access-modifier.html