Java 逆引き集 | 内部クラス(static / 非static / 匿名) — 小さなヘルパー実装

Java Java
スポンサーリンク

内部クラス(static / 非static / 匿名) — 小さなヘルパー実装

Javaではクラスの中にさらにクラスを定義できます。これを 内部クラス(nested class) と呼びます。
「外部クラスに密接に関係する小さなヘルパー」をまとめるのに便利です。種類は大きく static内部クラス非static内部クラス(インナークラス)匿名クラス の3つ。


static内部クラス(外部に依存しない)

特徴

  • 外部クラスのインスタンスに依存しない。
  • 外部クラスの staticメンバ にアクセスできる。
  • ユーティリティ的な補助クラスをまとめたいときに使う。

class Outer {
    static int base = 10;

    static class Helper {
        int calc(int x) {
            return base + x; // staticメンバにアクセス可能
        }
    }
}

Outer.Helper h = new Outer.Helper();
System.out.println(h.calc(5)); // 15
Java

👉 外部クラスのインスタンス不要。 new Outer.Helper() で直接生成。


非static内部クラス(インナークラス)

特徴

  • 外部クラスのインスタンスに紐づく。
  • 外部クラスの インスタンスフィールドやメソッド にアクセスできる。
  • 外部クラスと強く結びついた処理をまとめたいときに使う。

class Outer {
    private String name = "Tanaka";

    class Inner {
        void hello() {
            System.out.println("Hello " + name); // 外部インスタンスのフィールドにアクセス
        }
    }
}

Outer o = new Outer();
Outer.Inner i = o.new Inner(); // 外部インスタンスから生成
i.hello(); // Hello Tanaka
Java

👉 外部インスタンスが必須。 o.new Inner() の形で生成。


匿名クラス(その場限りの即席)

特徴

  • 名前を付けずに、その場でクラスを定義してインスタンス化。
  • 一度きりの小さな実装に便利。
  • よく使う場面: インターフェースや抽象クラスの即席実装。

interface Greeter {
    void greet();
}

Greeter g = new Greeter() {
    @Override
    public void greet() {
        System.out.println("こんにちは!");
    }
};

g.greet(); // こんにちは!
Java

👉 一度きりの小さな処理をその場で書ける。Java8以降はラムダ式でさらに簡潔に書ける。


例題で練習

例題1: static内部クラスでユーティリティ

class MathUtil {
    static class Adder {
        int add(int a, int b) { return a + b; }
    }
}
MathUtil.Adder adder = new MathUtil.Adder();
System.out.println(adder.add(3, 4)); // 7
Java

👉 外部クラスのインスタンス不要。


例題2: 非static内部クラスで外部状態を利用

class Person {
    private String name;
    Person(String name) { this.name = name; }

    class Printer {
        void print() { System.out.println("Name=" + name); }
    }
}

Person p = new Person("Sato");
Person.Printer pr = p.new Printer();
pr.print(); // Name=Sato
Java

👉 外部インスタンスのフィールドに直接アクセスできる。


例題3: 匿名クラスで一度きりの処理

Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("タスク実行");
    }
};
new Thread(r).start();
Java

👉 即席のRunnable実装。 Java8以降なら new Thread(() -> System.out.println("タスク実行")).start(); と書ける。


テンプレート集

static内部クラス

class Outer {
    static class Inner {
        // 外部クラスのstaticメンバにアクセス可能
    }
}
Outer.Inner obj = new Outer.Inner();
Java

非static内部クラス

class Outer {
    class Inner {
        // 外部クラスのインスタンスメンバにアクセス可能
    }
}
Outer o = new Outer();
Outer.Inner i = o.new Inner();
Java

匿名クラス

InterfaceType obj = new InterfaceType() {
    @Override
    public void method() { /* 実装 */ }
};
Java

まとめ

  • static内部クラス: 外部インスタンス不要。ユーティリティや補助的なまとまり。
  • 非static内部クラス: 外部インスタンスに紐づく。外部の状態を直接利用。
  • 匿名クラス: 一度きりの即席実装。小さな処理をその場で。

👉 練習課題として「イベントリスナー」を匿名クラスで書き換えたり、「外部クラスの状態を出力するPrinter」を非static内部クラスで作ると、内部クラスの違いが体感できます。

タイトルとURLをコピーしました