どくぴーの備忘録

真面目なことを書こうとするクソメガネのブログ。いつ投げ捨てられるのかは不明

Javaのenumで定数を分岐させたい

enumって

列挙型と言われる.一連の値を定義する文法.Javaでも使える.

よく

public static final int HOGE = 1;
public static final int FUGA = 2; 

とかいう形で定数を扱うけど,

public enum Piyo{HOGE,FUGA}

みたいにしておけばintメンバが氾濫しなくなるので(個人的に)スッキリする.また,enumの中に記された値以外の値をブロックできるようになるので,「想定していない値が来た」ときの処理を考えなくて良くなるのがよい

Javaにおけるenum

qiita.com

Javaenumというのは,Cのenumみたいなintを列挙をものではなく,オブジェクトの列挙になるので,enum1つ1つにメンバ変数,メソッドを持たせ,振る舞いをつけることができる.

public enum SelesEnum{
    Tomato(100),
    Potato(150),
    Carrot(120);

    private final int price;

    //コンストラクタは必ずprivateに!
    private SalesEnum(final int price){
        this.price = price;
    }

    public int getPrice(){
        return price;
    }
}

こうしてやることで SalesEnum.Tomato.getPrice()150 が返ってくる.enumはあくまで「プログラム実行時にオブジェクトとして保持する」定数であってインスタンスを持ってはいけないので,シングルトンにするためにコンストラクタはprivateにするように.細かいことは上記記事やEffective Javaを見よう.

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)

定数を分岐

例えば「手元のバージョン等の違いで利用する定数を無意識的に変更したい」という場合,enumを使わないと

public final static String[] VERSION_STRING = {"v1.0.0", "v1.2.0", "v1.5.0"};
public final static int V1_0_0 = 1;
public final static int V1_2_0 = 2;
public final static int V1_5_0 = 3;


public String getVersionString(Version version){
    if(version.num == V1_0_0) return VERSION_STRING[0];
    else if(version.num == V1_2_0) return VERSION_STRING[1];
    else if(version.num == V1_5_0) return VERSION_STRING[2];
    return null; // エラー処理とか
}

とかこんなかんじに,長ったらしいし,今後バージョンが増えた時にまた新たにintを割り当てて…となかなか面倒.

そこで,enumを使うと

enum Version{
    V1_0_0, V1_2_0, V1_5_0
}

public enum VersionsEnum{
    VERSION_STRING(new String[]{"v1.0.0", "v1.2.0", "v1.5.0"});

    private final String[] versionStrings;

    //コンストラクタは必ずprivateに!
    private VersionsEnum(final String[] versionStrings){
        this.versionStrings = versionStrings;
    }

    public String getVersionString(Version v){
        if(v == Version.V1_0_0) return versionStrings[0];
        else if(v == Version.V1_2_0) return versionStrings[1];
        else if(v == Version.V1_5_0) return versionStrings[2];
        return null;
    }
}

実際のコード量は増えたが,今後バージョンが増えたり,新たにメンバ変数を増やさないといけなくなった時に,簡単に変更が加えられる(と思う).

Javaenumに振るまいをもたせる記事は探せば結構あったのだが,こういう事している記事はStackOverflow以外で見かけなかったので,メモ代わりに….

終わりに

int定数でごちゃごちゃ書いているんだったらenum化して幸せになろうな,ってお話でした