まず、用語が混乱しやすいので整理しておくと、
- クラスの中にさらにクラスを定義したとき、その内側のクラスはネステッドクラス(nested class)という。
- また、内部クラスを囲っている外側のクラスはエンクロージングクラス(enclosing class)という。
ネステッドクラスには以下の4種類がある。
- スタティック ネステッドクラス(static nested class)
- インナークラス(inner [non-static] class)
- ローカルクラス(local)
- 無名クラス(anonymous class)
ネステッドクラスのうち、ローカルクラスについては以前の記事で扱ったので、今回はインナークラスについて見ていく。
まず、インナークラスの定義例は次のようになる。
class MyClass{ class MyInnerClass{ } }
JavaのインナークラスはC#やC++とは違い、エンクロージングクラスのインスタンスに関連付けられる。このため、外部クラスのプライベートメンバに直接アクセスできたりする。
制限として、外部クラスのインスタンスが無ければインナークラスのインスタンスを作ることはできない。
実際にインスタンスを作りたいときは、
MyInnerClass hoge = new MyClass().new MyInnerClass();
という感じの宣言になる。
しかし、わざわざインナークラスで定義したものをエンクロージングクラスの外側で
インスタンス化するというのはそもそも設計が間違っている気がするし、
こういった状況が必要なことはほぼないだろうと思う。
インナークラスにstatic修飾子を付けると、そのクラスはエンクロージングクラスに依存しなくなる。
class MyClass{ static class MyNestedClass{ } } // インスタンス化してみる MyNestedClass m = new MyNestedClass(); // OK
感覚としてはエンクロージングクラスが一つのパッケージになったようなものである。
しかしこちらも、別にパッケージを定義すればいい話であるし、スタティックネステッドクラスに関しては
ほとんど使いどころは無いだろうと思う。
インナークラスについての解説は、やはり@ITのこの記事が詳しい。