TypeSafeEnumを知る
定数を管理するときの話。
昔は定数クラスとか作ってゴリゴリ書いてたけど、可読性も悪いし、管理も大変だった。
なので、java5からあるenumを使ってみたが、継承が出来ないので、使い勝手が悪かった。。
そんなときに、TypeSafeEnumを知ったので、自分なりに書いてみた。
TypeSafeEnumクラス
/** * TypeSafeEnumを作ってみる */ public class TypeSafeEnum { /** * NULL */ public static final TypeSafeEnum NULL = new TypeSafeEnum(null); /** * Enumマップ */ protected static final Map<String, Object> ENUM_MAP = new HashMap<String, Object>(); /** * 区分値 */ private String value; /** * コンストラクタ * @param value 区分値 */ protected TypeSafeEnum(String value) { this.value = value; } /** * 区分値を取得する * @return 区分値 */ public String value() { return value; } /** * NULL値かどうか * @return true:NULL値、false:NULL値でない */ public boolean isNull() { return this == NULL; } /** * 区分値からインスタンスを取得する * @param <T> {@link TypeSafeEnum}を継承したクラス * @param value 区分値 * @return インスタンス */ @SuppressWarnings("unchecked") public static <T extends TypeSafeEnum> T valueof(String value) { if (!ENUM_MAP.containsKey(value)) { return (T) NULL; } return (T) ENUM_MAP.get(value); } /** * 区分値のリストを取得する<br> * @param <T> {@link TypeSafeEnum}を継承したクラス * @return 区分値のリスト */ @SuppressWarnings("unchecked") public static <T extends TypeSafeEnum> List<T> values() { List<T> enumList = new ArrayList<T>(); for (Entry<String, Object> enumEntry : ENUM_MAP.entrySet()) { enumList.add((T) enumEntry.getValue()); } return enumList; } }
TypeSafeEnumを継承した区分値クラス
/** * 血液型区分 */ public class BloodType extends TypeSafeEnum { /** * A型 */ public static final BloodType A = new BloodType("A型"); /** * B型 */ public static final BloodType B = new BloodType("B型"); /** * O型 */ public static final BloodType O = new BloodType("O型"); /** * AB型 */ public static final BloodType AB = new BloodType("AB型"); /** * コンストラクタ * @param value 区分値 */ private BloodType(String value) { super(value); } /** * 区分値マップを初期化 */ static { ENUM_MAP.put("A型", A); ENUM_MAP.put("B型", B); ENUM_MAP.put("O型", O); ENUM_MAP.put("AB型", AB); } /** * A型であるかどうか * @return true:A型、false:A型でない */ public boolean isA() { return this == A; } /** * B型であるかどうか * @return true:B型、false:B型でない */ public boolean isB() { return this == B; } /** * O型であるかどうか * @return true:O型、false:O型でない */ public boolean isO() { return this == O; } /** * AB型であるかどうか * @return true:AB型、false:AB型でない */ public boolean isAB() { return this == AB; } }
なるべく継承クラスには、区分値の定義のみをさせるようにした。
まだまだ、改良の余地はあるがとりあえず版。。