2013年6月18日火曜日

[Java][Android]Enum型を使う(Performance Tipsを読み直す)

Android DevelopersのPerformance Tipsには、パフォーマンス/サイズ上の理由からenumの利用を避けるべき。との方針がありました。んで、最新版を読み直してみるとその記述が消えていました。

とあるサイトによると、enumを1つで1KBくらいのサイズが余分に使われる。とのことでした。でも、最近のハードウェアではそんなの微々たるものだよな。と思っていました。
あと、インタフェース型での参照を使わない。っていうのも消えている様子。この辺はAndroidを初めたころ、すごく違和感があったことを記憶しています。

ということで、intからenumに変えるとどんな感じかを書いてみました。
各々の方式でオーディオプレイヤーのステータスを表現するとこんな感じ。

■intで表現した場合
static class Status {
    /** 停止. */
    static final int stop = 0;
    /** 一時停止. */
    static final int pause = 1;
    /** 再生. */
    static final int play = 2;
    /** 早送. */
    static final int next = 10;
    /** 巻戻. */
    static final int prev = 11;
    /** 録音. */
    static final int rec = 20;

    /** 再生中のSet. */
    static final private Set<Integer> STAT_PLAY = new HashSet<Integer>();
    static {
        STAT_PLAY.add(pause);
        STAT_PLAY.add(play);
    }

    /** 再生中. */
    static boolean isPlaying(int stat) {
        return STAT_PLAY.contains(stat);
    }

    /** 停止中. */
    static boolean isStoped(int stat) {
        return stat == stop;
    }

    /** 動作中. */
    static boolean isOperating(int stat) {
        return stat == stop;
    }
}

■enumで表現した場合
public enum Status {
    /** 停止. */
    stop(0),
    /** 一時停止. */
    pause(1),
    /** 再生. */
    play(2),
    /** 早送. */
    next(10),
    /** 巻戻. */
    prev(11),
    /** 録音. */
    rec(20);

    /** 値. */
    private int value = 0;

    /** 再生中のSet. */
    static final private Set<Status> STAT_PLAY = EnumSet.of(pause, play);

    /**
     * コンストラクタ.
     *
     * @param value
     */

    private Status(int value) {
        this.value = value;
    }

    /** 再生中. */
    public boolean isPlaying() {
        return STAT_PLAY.contains(this);
    }

    /** 停止中. */
    public boolean isStoped() {
        return stop == this;
    }

    /** 動作中. */
    public boolean isOperating() {
        return stop != this;
    }

}

利用はこんな感じ。メリット的には

  • タイプセーフ。他の数値を誤って指定できない
  • メソッドが実装できます。 isXXX系を実装すると便利

まぁ、一般論ですね。利用例はこんな感じ。

EnumEnum e = new EnumEnum();
// タイプセーフ。Statusしか渡せない    
e.enumTest(Status.play);
  

public boolean enumTest(Status stat){
    // enumなら、メソッドを実装できる
    return stat.isPlaying();
}


一時期は、利用を控えてみましたが、Performance Tipsから消えたことだし、enumをバンバン使っていく方向で行きましょう。

0 件のコメント: