Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

staticな内部クラスは内部クラスじゃあない

From

Java魂―プログラミングを極める匠の技

Java魂―プログラミングを極める匠の技


後輩に内部クラスのことを聞かれました。ちょっとまとめ。
内部クラスと呼ぶためには外部クラスのインスタンス変数にアクセスできないといけない。つまり、内部クラスは外部クラスのインスタンス変数を扱える。
まずは普通の内部クラス。

public class OuterClass {

	private String instanceVariable = "test";

	public static void main(String[] args) {
		OuterClass outerClass = new OuterClass();
		InnerClass innerClass = outerClass.new InnerClass();
		innerClass.accessOuterClass();
	}

	class InnerClass {
		void accessOuterClass() {
			System.out.println("result:" + instanceVariable);
		}
	}
}

実行結果

result:test

内部クラスの生成には外部クラスのインスタンスが必要。

		OuterClass outerClass = new OuterClass();
		InnerClass innerClass = outerClass.new InnerClass();

とか

		InnerClass innerClass = new OuterClass().new InnerClass();

でOK。微妙に気持ち悪い。
このInnerClassにstaticをつけちゃうと、staticなだけに外部クラスのインスタンス変数にアクセスできなくなる。

	static class InnerClass {
		void accessOuterClass() {
			System.out.println("result:" + instanceVariable);←コンパイルエラー
		}
	}

だからstaticな内部クラスは内部クラスと呼べなくなっちゃう。
ただ、外部クラスのインスタンス変数が必要な場合ってなかなかない気がする。読みやすさを考えたらstaticつけられるならつけといた方がいいってことだね。
ちなみにstaticをつけた場合、InnerClassのインスタンスは普通のクラスと同じ形で生成する。

public class OuterClass {

	public static void main(String[] args) {
		InnerClass innerClass = new InnerClass();
		innerClass.accessOuterClass();
	}

	static class InnerClass {
		void accessOuterClass() {
			System.out.println("called");
		}
	}
}
		InnerClass innerClass = new InnerClass();