Enum

これまでJavaでenumのようなことをやろうと思うと、intで代用するか、 Javaの鉄則でかかれているようなクラスを作ってやるかくらいしか方法が ありませんでした。JDK1.5で導入されたenumは、コンストラクタや メソッド、フィールドが定義できる点など、ほとんどclassと同じに なっています。

非常にシンプルなものだと、

public enum ColorEnum {RED, GREEN, BLUE}
で終わりです。全てのenumには、全要素の配列を返すstaticメソッドvalues()が 定義されているので、
	ColorEnum[] colors = ColorEnum.values();
	for (ColorEnum c : colors) {
		System.out.println(c);
	}
とやると、
RED
GREEN
BLUE
と表示されます。順序がちゃんと保証されているのですね。またenumの要素を そのままSystem.out.println()に渡せるのも便利です。toString()メソッドが 要素の名前を返すようになっているのですね。

でもEnumの要素名に日本語を使うことができませんから、プログラム内部では 英文字、プリントアウトする時は和字というのを実現しようとすると、ちょっと 細工が必要になって、コンストラクタとtoString()を定義しないといけません。

public enum ColorEnum {
	RED("赤"),
	BLUE("青"),
	GREEN("緑");

	// プリントアウトする時の名前
	private String name;

	/**
	 * コンストラクタ。publicにすることはできない。
	 * privateはOK。いずれにせよ外部からインスタンスを生成することはできない。
	 */
	ColorEnum(String name) {
		this.name = name;
	}

	public String toString() {
		return name;
	}
}
てな具合です。こうすると
赤
青
緑
と出力されるようになります。

コメントに書いたようにenumの要素を外部でインスタンス化(つまりnewすること)が できない(コンパイラがはねる)ようになっています。従ってenumの変数は定義された 要素以外には決してならないとしてプログラムを作成できます。このあたりは intで代用する場合に比べてのメリットです。しかしenumの変数はnullにすること ができます。

	ColorEnum color = null;
はOKなのです。このためenumを引数にとるメソッドでのnullチェック(または呼び出し 側でのチェック)が必要になります。この点は仕様に不満に感じるところです。

enumはswitch文のcase節で使用することもできます。この点はクラスのオブジェクト で代用する場合に比べてのメリットです。

	switch (color) {
	case RED:
	case GREEN:
	case BLUE:
		System.out.println("color is " + color);
		break;
	default:
		throw new AssertionError("Unknown ColorEnum" + this);
	}
と書けるわけです(default節はなくとも困らないし)。

java.utilに追加されたEnumSetとEnumMapも確認しておいたほうが良い機能でしょう。 EnumSetはenumの部分enumを簡単に作成することができます。EnumMapはenumの要素を キーとするMapの実装です。内部で配列を使用することで高速に動作するMapになって いるとの事ですので、使い手はあるでしょう。


JDK5.0  人材開発室 PoisonSoft