m-saitoh’s blog

SE・PGのフリーランスになったメモ

javaの定数とenum

javaの定数クラスとenum

定数クラスではサブクラスを定義して、意味のある単位に纏める
DBのコードマスタみたいなデータのコードから名称を取得できるenum

大本になる定数クラス
ここにコードから名称を取得するためのインターフェイスと部品を作成して置く

import java.util.Arrays;

/**
 * 定数クラス<br />
 */
public class SystemConstant {

    /**
     * コード値から名称を取得するためのI/F<br />
     * ここでの名称とは列挙子.nameでは無い<br />
     * 参考サイト
     * <li>http://www.casleyconsulting.co.jp/blog-engineer/java/%E5%86%8D%E5%B8%B0%E7%9A%84%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%82%AF%E3%82%B9%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%9Fjava8%E6%99%82%E4%BB%A3%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89%E5%AE%9A/
     * 
     */
    public interface CodeEnum<E extends Enum<E>> {
        /** コード取得 */
        String getCode();

        /** 名称取得 */
        String getName();

        /** [デフォルト実装] Enumに変換する */
        @SuppressWarnings("unchecked")
        default E toEnum() {
            return (E) this;
        }

        /** [デフォルト実装] コード値が同一かどうかをチェックする */
        default boolean equalsByCode(String code) {
            return getCode().equals(code);
        }

        /** [staticメソッド] 指定されたCodeEnumを実装したEnumの、指定されたコード値の列挙子を返却する */
        static <E extends Enum<E>> E getEnum(Class<? extends CodeEnum<E>> clazz, String code) {
            return Arrays.stream(clazz.getEnumConstants())
                    .filter(e -> e.equalsByCode(code))
                    .map(CodeEnum::toEnum)
                    .findFirst()
                    .orElse(null);
        }

    }


各処理パッケージ毎に宣言する定数クラス enumはCodeEnumをインプリメントする事によってコードから名称を取得出きるようになる

/**
 * B系パッケージの定数
 *
 */
public class BravoConstant extends SystemConstant {

    /** B系の画面遷移定数 */
    public class ScreenTransition {
        public static final String B0101 = "/ront2/bravo/b01/b0101";
        public static final String B0201 = "/ront2/bravo/b02/b0201";
    }

    /**
     * 和暦の定数
     * <li>明治
     * <li>大正
     * <li>昭和
     * <li>平成
     */
    public enum MyJapaneseEra implements CodeEnum<MyJapaneseEra> {

        MEIJI("M", "明治", "1868~1912"),
        TAISHO("t", "大正", "1912~1926"),
        SHOWA("S", "昭和", "1926~1989"),
        HEISEI("H", "平成", "1989~");

        private String code;
        private String name;
        private String description;

        MyJapaneseEra(String code, String name, String description) {
            this.code = code;
            this.name = name;
            this.description = description;
        }

        @Override
        public String getCode() {
            return code;
        }

        @Override
        public String getName() {
            return name;
        }

        public String getDescription() {
            return description;
        }

    }

}


使い方

        Optional<MyJapaneseEra> opt = Optional
                .ofNullable(CodeEnum.getEnum(MyJapaneseEra.class, "M"));// ここのMは画面orDBから取得した値を想定
        MyJapaneseEra myEra = opt.orElse(MyJapaneseEra.HEISEI);
        log.debug(myEra.getName()); // 明治
        log.debug(myEra.getDescription()); // 1868~1912
        log.debug(myEra.name()); // MEIJI