Android: 列挙にはenumではなくIntDef, StringDef annotationを使う

Android: 列挙にはenumではなくIntDef, StringDef annotationを使う

月(month)を定義する

例えば, 月をenumで定義する場合は以下のように書くことが出来ます.

enum Month {
    JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
    JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
}

また, 定数(int)を使うとしたら以下のように書くことが出来ます.

static final int JANUARY = 1;
static final int FEBRUARY = 2;
static final int MARCH = 3;
static final int APRIL = 4;
...
static final int NOVEMBER = 11;
static final int DECEMBER = 12;

定数を使うバージョンだと, int型以上の情報がなく(月の情報がない), type-safeではありません. enumの場合は, getDate(Month)のため, type-safeを提供してくれます. これは, 大きなメリットです.

しかし, enumは, 定数を使うバージョンと比較すると, apkサイズが大きくなってしまうデメリットがあります. Androidではメモリリソースはとても貴重なため, enumを使うのは極力避けたほうが良いです.

Androidでは, IntDef(StringDef) annotationを使うことで, type-safeに定数を使うことが出来ます.

上記のMonthのコードをIntDef annotationを使い, 書き換えてみます.

// Monthに代入することが出来る定数を宣言
@IntDef({JANUARY, FEBRUARY, MARCH, APRIL, ...})
@Retention(RetentionPolicy.SOURCE)
public @interface Month {};
static final int JANUARY = 1;
static final int FEBRUARY = 2;
static final int MARCH = 3;
static final int APRIL = 4;
...

int getDate(@Month int month) {
    ////
}

Month annotationをIntDefで定義し, getDate(@Month int)と書くことでtype-safeにgetDateメソッドを宣言することが出来ます. この書き方は, 「enumのtype-safe」と「定数のパフォーマンス」を満たしています.

まとめ

参考