パンくず
Effective Java
int定数の代わりにenumを使用する
概要
int定数の代わりにenumを使用する
詳細
int enumパターン
特定の数値に意味を持たせて定数化する方法。
この方法に文法的な縛りは何もなく、せいぜい定数名を合わせることで多少分かりやすくする程度だった。
実際にその定数数値に対応した文字列を表示させる方法がなかった。
/* --- int enumパターン --- */ /** 言語 Java */ public static int LANGUAGE_JAVA = 0; /** 言語 Ruby */ public static int LANGUAGE_RUBY = 1; /** 言語 PHP */ public static int LANGUAGE_PHP = 2;
String enumパターン
特定の文字列に意味を持たせて定数化する方法。
こちらは文字列を表示することが可能だが、文字列比較のためパフォーマンスに問題がある。
/* --- String enumパターン --- */ /** 言語 Java */ public static String LANGUAGE_STRING_JAVA = "Java"; /** 言語 Ruby */ public static String LANGUAGE_STRING_RUBY = "Ruby"; /** 言語 PHP */ public static String LANGUAGE_STRING_PHP = "PHP";
enumサンプル・コード仕様
言語enumは数値のコードと言語種別を持つ。
言語種別もEnumで定義され、オブジェクト指向言語、手続き型言語などを表す。
数値コードからEnumを取得するメソッドを提供。
DBにEnumに対応するコード値を保持している場合などに重宝する。
特定の言語種別のEnumをListで取得するメソッドを提供。
このようにEnumと関連するメソッドを容易に追加出来るのがenum型のメリット。
enumサンプル・コード
package effective.creation.chapter6; import java.util.ArrayList; import java.util.List; public class SampleNo30 { /* --- int enumパターン --- */ /** 言語 Java */ public static int LANGUAGE_JAVA = 0; /** 言語 Ruby */ public static int LANGUAGE_RUBY = 1; /** 言語 PHP */ public static int LANGUAGE_PHP = 2; /* --- String enumパターン --- */ /** 言語 Java */ public static String LANGUAGE_STRING_JAVA = "Java"; /** 言語 Ruby */ public static String LANGUAGE_STRING_RUBY = "Ruby"; /** 言語 PHP */ public static String LANGUAGE_STRING_PHP = "PHP"; /** 言語 */ public enum Language { JAVA(0, LanguageType.OBJECT_ORIENTED), RUBY(1, LanguageType.OBJECT_ORIENTED), PHP(2, LanguageType.OBJECT_ORIENTED), SCALA( 3, LanguageType.FUNCTIONAL), C(4, LanguageType.PROCEDURAL); private final int code; private final LanguageType type; Language(int code, LanguageType type) { this.code = code; this.type = type; } /** * 言語コードを元に言語を取得する。 * * @param code * @return 言語 */ public static Language fromIntValue(int code) { for (Language eachLanguage : Language.values()) { if (eachLanguage.code == code) { return eachLanguage; } } throw new IllegalArgumentException(); } /** * 言語種別を元に対応する言語のリストを取得する。 * * @param type 言語種別 * @return 言語リスト */ public static List<Language> getLanguages(LanguageType type) { List<Language> languageList = new ArrayList<Language>(); for (Language eachLanguage : Language.values()) { if (eachLanguage.type == type) { languageList.add(eachLanguage); } } return languageList; } public int languageCode() { return code; } public LanguageType languageType() { return type; } } /** 言語種別 */ public enum LanguageType { OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL } public static void main(String[] args) { System.out.println(LANGUAGE_JAVA); System.out.println(LANGUAGE_RUBY); System.out.println(LANGUAGE_PHP); System.out.println("-----------------------------------------------------"); System.out.println(LANGUAGE_STRING_JAVA); System.out.println(LANGUAGE_STRING_RUBY); System.out.println(LANGUAGE_STRING_PHP); System.out.println("-----------------------------------------------------"); // 全言語を出力 for (Language eachLanguage : Language.values()) { printLanguageDetail(eachLanguage); } System.out.println("-----------------------------------------------------"); // オブジェクト指向言語を出力 for (Language eachObjectOrientedLanguage : Language.getLanguages(LanguageType.OBJECT_ORIENTED)) { printLanguageDetail(eachObjectOrientedLanguage); } System.out.println("-----------------------------------------------------"); System.out.println(Language.valueOf("JAVA")); } private static void printLanguageDetail(Language eachLanguage) { System.out.print(eachLanguage); System.out.print(","); System.out.print(eachLanguage.code); System.out.print(","); System.out.println(eachLanguage.type); } }
出力
0 1 2 ----------------------------------------------------- Java Ruby PHP ----------------------------------------------------- JAVA,0,OBJECT_ORIENTED RUBY,1,OBJECT_ORIENTED PHP,2,OBJECT_ORIENTED SCALA,3,FUNCTIONAL C,4,PROCEDURAL ----------------------------------------------------- JAVA,0,OBJECT_ORIENTED RUBY,1,OBJECT_ORIENTED PHP,2,OBJECT_ORIENTED