switchステートメントでenumを使用するJava


106

この質問に似たSOに関するさまざまなQ&Aを確認しましたが、解決策は見つかりませんでした。

私が持っているのは、テレビガイドを表示するさまざまな方法を表す列挙型です...

NDroid Applicationクラス

static enum guideView {
    GUIDE_VIEW_SEVEN_DAY,
    GUIDE_VIEW_NOW_SHOWING,
    GUIDE_VIEW_ALL_TIMESLOTS
}

...ユーザーがビューを変更すると、イベントハンドラは intようなことをしたいと思います...

Android Activity onClick(DialogInterface dialog, int which)イベントハンドラー

// 'which' is an int from 0-2
switch (which) {
    case NDroid.guideView.GUIDE_VIEW_SEVEN_DAY:
    ...
    break;
}

C#の列挙型とselect / caseステートメントに慣れているため、上記のようなことが可能になり、Javaの動作が異なることはわかっていますが、必要なことを理解できません。

if声明に頼らなければならないのでしょうか?おそらく3つの選択肢しかないので、私はそれを行うことができますが、Javaでスイッチケースを使用してどのように実行できるのか疑問に思いました。

編集申し訳ありませんが、私はそれを一般的なJavaの問題であると見なしていたため、この問題を完全に拡張しませんでした。もう少し説明するために質問に追加しました。

Android固有のものはありません。そのため、Androidとしてタグ付けしませんでしたが、列挙型はApplicationクラス内で定義されており、スイッチに入れたくないコードはにありActivityます。複数のアクティビティからアクセスする必要があるため、列挙型は静的です。


1
case GUIDE_VIEW_SEVEN_DAY適切にインポートした後でなければなりません。どのような問題がありますか?
デイブニュートン

イベントハンドラーに列挙型を受信させるだけではいいですか?それはさておき、おそらくこれが役立ちます:stackoverflow.com/questions/5292790/...
ブライアン・ローチ

@Dave:申し訳ありません。コードを修正して、その状態を示しました。Eclipseは、guideViewからintに変換できないというタイプミスマッチエラーを私に与えています。
Squonk 2011年

@ブライアン:これはAndroidアプリであり、イベントハンドラー(OnClickListener )はDialogInterface、実装する必要があるインターフェイスによって定義されます。
Squonk 2011年

@MisterSquonkああ、あなたはintからそれを取得しているのを逃しました-申し訳ありませんが、私は列挙型に機能を入れましたが、Ophidianの回答を参照してください。
デイブニュートン

回答:


162

不足している部分は、整数から型保証された列挙型への変換です。Javaは自動的には行いません。これに対処する方法はいくつかあります。

  1. タイプセーフな列挙型ではなく静的な最終整数のリストを使用し、受け取るint値をオンにします(これはJava 5より前のアプローチです)
  2. 指定されたID値(heneryvilleで説明されている)または列挙値の序数値のいずれかをオンにします。すなわちguideView.GUIDE_VIEW_SEVEN_DAY.ordinal()
  3. int値で表される列挙値を決定し、列挙値をオンにします。

    enum GuideView {
        SEVEN_DAY,
        NOW_SHOWING,
        ALL_TIMESLOTS
    }
    
    // Working on the assumption that your int value is 
    // the ordinal value of the items in your enum
    public void onClick(DialogInterface dialog, int which) {
        // do your own bounds checking
        GuideView whichView = GuideView.values()[which];
        switch (whichView) {
            case SEVEN_DAY:
                ...
                break;
            case NOW_SHOWING:
                ...
                break;
        }
    }

    valueOf適切な列挙値を解決するために引数として整数値を取り、境界チェックを集中化できるカスタム実装を作成する方が、より便利でエラーが少ない傾向があります。


どうもありがとう。コードに組み込むのに少し時間がかかりましたが、投稿したサンプルコードで問題なく動作しています。C#で6年間、Javaで1年間-私が困惑するようなものに出くわすことはあまりありません。非常に多くの類似点がありますが、このような非常に異なる時折の類似点があります。これを急いで忘れません。:-)
Squonk 2011年

2
あなたはcase文で修飾されていない列挙名を必要とするのでcase GuideView.SEVEN_DAY:、コンパイルエラーを与えます、それはそうであるべきですcase SEVEN_DAY:
haridsv 14

それは素晴らしい仲間です!!
Neo

41

whichViewがGuideView Enumのオブジェクトである場合、以下がうまく機能します。後の定数の修飾子がないことに注意してくださいcase

switch (whichView) {
    case SEVEN_DAY:
        ...
        break;
    case NOW_SHOWING:
        ...
        break;
}

4
これはどうすれば可能ですか?
Jes Chergui 2014年

12

enumはNDroid.guideView.GUIDE_VIEW_SEVEN_DAY、所有しているもののようにケースラベル内で修飾されるべきではなく、代わりに修飾を削除して使用する必要がありますGUIDE_VIEW_SEVEN_DAY


これを好む。シンプル!
Lazy Ninja

5

Java enumのいくつかの使用法が好きです。

  1. .name()を使用すると、列挙名をStringでフェッチできます。
  2. .ordinal()を使用すると、0ベースの整数値を取得できます。
  3. 各列挙型に他の値パラメーターをアタッチできます。
  4. そしてもちろん、スイッチが有効になっています。

値パラメーターを持つ列挙型:

    enum StateEnum {
        UNDEFINED_POLL  ( 1 * 1000L,       4 * 1000L),
        SUPPORT_POLL    ( 1 * 1000L,       5 * 1000L),
        FAST_POLL       ( 2 * 1000L,  4 * 60 * 1000L),
        NO_POLL         ( 1 * 1000L,       6 * 1000L); 
        ...
    }

スイッチの例:

private void queuePoll(StateEnum se) {
    // debug print se.name() if needed
    switch (se) {
        case UNDEFINED_POLL:
            ...
            break;
        case SUPPORT_POLL:
            ...
            break;

3

これは、あなたが説明した方法で機能するはずです。どのようなエラーが発生していますか?あなたがコードをペーストビンすることができればそれは助けになるでしょう。

http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

編集:静的列挙型を定義してもよろしいですか?それは私には正しく聞こえません。列挙型は他のオブジェクトとよく似ています。コードがコンパイルされて実行されても、結果が正しくない場合は、おそらくこれが理由です。


「ネストされた列挙型は暗黙的に静的です。ネストされた列挙型を静的であると明示的に宣言することは許可されています。」— JLS§8.9
ゴミ神

@trashgod、確かに-しかし、混乱を避けるために暗黙の宣言を常に使用しますが、これは実際にはより明白なIMOです。グローバル静的列挙型(これは私が想定しているものです)は、ほとんどの場合、おそらく間違っています。
SystemParadox

2
enumerations accessing is very simple in switch case

private TYPE currentView;

//declaration of enum 
public enum TYPE {
        FIRST, SECOND, THIRD
    };

//handling in switch case
switch (getCurrentView())
        {
        case FIRST:
            break;
        case SECOND:
            break;
        case THIRD:
            break;
        }

//getter and setter of the enum
public void setCurrentView(TYPE currentView) {
        this.currentView = currentView;
    }

    public TYPE getCurrentView() {
        return currentView;
    }

//usage of setting the enum 
setCurrentView(TYPE.FIRST);

avoid the accessing of TYPE.FIRST.ordinal() it is not recommended always

これは、データを外部から取得していない場合にのみ機能します。OPはリターンがその値は言ったので1、2、3ないTYPEあなたの方法だろう...、2、1 3を取り、彼がリストされたスイッチケースに入る前に型を返し逆転スイッチケースがないわけではない仕事
WORMSS

2

短い連想関数の例:

public String getIcon(TipoNotificacao tipo)
{
    switch (tipo){
        case Comentou : return "fa fa-comments";
        case ConviteEnviou : return "icon-envelope";
        case ConviteAceitou : return "fa fa-bolt";
        default: return "";
    }
}

@Dhanushkaが言ったように、「スイッチ」内の修飾子を省略することが重要です。


1

私はそれをやっています

public enum State
{
    // Retrieving, // the MediaRetriever is retrieving music //
    Stopped, // media player is stopped and not prepared to play
    Preparing, // media player is preparing...
    Playing, // playback active (media player ready!). (but the media player
                // may actually be
                // paused in this state if we don't have audio focus. But we
                // stay in this state
                // so that we know we have to resume playback once we get
                // focus back)
    Paused; // playback paused (media player ready!)

    //public final static State[] vals = State.values();//copy the values(), calling values() clones the array

};

public State getState()
{
        return mState;   
}

そして、Switchステートメントで使用

switch (mService.getState())
{
case Stopped:
case Paused:

    playPause.setBackgroundResource(R.drawable.selplay);
    break;

case Preparing:
case Playing:

    playPause.setBackgroundResource(R.drawable.selpause);
    break;    
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.