読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

ネストクラスについて

Android Java

概要

ネストクラスについてもやもやしていたところをまとめる

詳細

親クラスのことをエンクロージングクラス、子クラスのことをネストクラスという
ネストクラスは以下の4つにわけられる

  • staticメンバークラス
  • 非staticメンバークラス
  • 匿名クラス
  • ローカルクラス

匿名クラスとローカルクラスはお馴染みなので説明省く

staticメンバークラス

一般的なstaticメンバークラス

public class MyClass {
	private String str1 = "top";
	private static String str2 = "top(class)";

	public static void main(String[] args) {
		HelperClass helper = new HelperClass();
		helper.show(new MyClass);
		System.out.println(helper.str1);		// nest
		System.out.println(helper.str2);		// nest(class)
	}

	private static class HelperClass {
		private String str1 = "nest"
		private static String str2 = "nest(class)"

		private void show(MyClass clazz) {
			System.out.println(clazz.str1);		// top
			System.out.println(MyClass.str2);	// top(class)	
		}
	}
}

エンクロージングクラスとメンバークラスとでは、クラスメンバーには「クラス名.メンバー名」、インスタンスメンバーには「オブジェクト名.メンバー名」でアクセスできる

非staticメンバークラス

public class MyClass {
	private String str1 = "top";
	private static String str2 = "top(class)";

	public static void main(String[] args) {
		MyClass clazz = new MyClass();
		clazz.hoge();
	}

	public void hoge() {
		// このインスタンス作成により暗黙的にエンクロージングオブジェクトの参照を持つ
		HelperClass helper = new HelperClass();
		helper.show();
		System.out.println(helper.helper1);		// nest
		System.out.println(HelperClass.helper2;	// nest(class)			
	}

	private class HelperClass {
		private String helper1 = "nest"
		private static String helper2 = "nest(class)"

		private void show() {
			System.out.println(MyClass.this.str1);		// top
			System.out.println(MyClass.str2);			// top(class)	
		}
	}
}

static修飾子の付かないメンバークラスのことを非staticメンバークラス、または内部クラスという
エンクロージングクラスに紐づくのではなくエンクロージングオブジェクトに属する点がstaticメンバークラスとは違う
そのため以下のような特徴がある

  • エンクロージングオブジェクトがないと、内部クラスはインスタンス化できない
  • 内部クラスからはthis変数で、エンクロージングクラスのインスタンスメンバーにアクセスできる

以上の理由から内部クラスは「エンクロージングクラスのインスタンスフィールドにアクセスする」用途では利用する、さもなければメンバークラスはstaticとするべき
個々のインスタンスがエンクロージングオブジェクトへの参照を保有しており、それは相応のメモリーを消費するため、また、余計な参照がエンクロージングオブジェクトの破棄を妨げることもある

参考

AndroidエンジニアのためのモダンJava

AndroidエンジニアのためのモダンJava