内部クラス(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内部クラスで作ると、内部クラスの違いが体感できます。
