Java:サブクラスの下の列挙型でswitchステートメントを使用する


265

最初に、私はC#の列挙型にかなり慣れていることを述べます。Javaの列挙型はかなり混乱しているようです。

ご覧のとおり、次の例ではswitchステートメント@ enumsを使用しようとしていますが、何をしている場合でも常にエラーが発生します。

私が受け取るエラーは:

修飾されたケースラベルSomeClass.AnotherClass.MyEnum.VALUE_Aは、修飾されていない列挙型定数で置き換える必要がありますVALUE_A

問題は私がエラーを完全に理解していることですが、列挙型が別のサブクラスにあるため、VALUE_Aを書き込むことはできません。この問題を解決する方法はありますか?そして、なぜそれがJavaで起こっているのですか?

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        MyEnum enumExample //...

        switch (enumExample) {
            case AnotherClass.MyEnum.VALUE_A: { <-- error on this line
                //..
                break;
            }
        }
    }
}

darrengormanがコメントしたように、Java Enumはコツをつかんだら非常に便利です。混乱することはありません。他のプラットフォームで見られるような単純な列挙型(単なるラベル付き整数値)よりもはるかに柔軟で実用的です。Oracleチュートリアルを参照してください。最適化されたSet/ Map実装を発見:EnumSetEnumMap
バジルブルク2017

1
ケースステートメントを修飾しようとすると、ある意味で、1つのswitchステートメント内で(同じenumタイプではなく)異なるタイプのenumを混在させることができるとあなたは言っています。ここで説明されているように、Javaはこのアプローチでこれを阻止しています。digizol.com
2010/10 /

IntelliJ 2018.2でクラスをリファクタリング(移動)しているときにこれが私に起こりました
Daniel Alder

回答:


570

これを次のように変更します。

switch (enumExample) {
    case VALUE_A: {
        //..
        break;
    }
}

手がかりはエラーです。case列挙型でラベルを修飾する必要はありません。その値だけです。


20
わかりました、私はとても愚かです:-(まったくそのとおりです。私はこの正確な行を試してエラーを得たと確信していたので、資格のあるケースに移動しましたが、あなたの提案は機能します
。– Popokoko

4
ちなみに、Javaの列挙型は、使い始めると信じられないほど役立つことに気づくと思いますが、それがめちゃくちゃであるとは決して言えません。:)
darrengorman

11
@milkplusvellocet、私はこの投稿がすでに古いことを知っていますが、Javaがswitchステートメントで修飾されたcaseラベルを許可しないのはなぜですか?
jzarsuelo

3
@ cRane01は確実にはわかりませんが、構文が簡潔になります。各ケースでタイプを指定することは完全に冗長です
darrengorman

3
@HelloGoodbyeいいえ。switchステートメントの変数は、caseステートメントのタイプを定義するため、列挙型は1つだけです。
スプリンター2015

33

Javaはの要素のタイプを自動的に推測するcaseため、ラベルは修飾されていない必要があります。

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}

14
なぜ無資格でなければならないのですか?
–ThorbjørnRavn Andersen 2015

11
資格を得ることができれば、MyEnum意味のないもの以外のものを使用する可能性があります。
Kru

1
@Kru、ただし、列挙型ではないcase式には、文法的に別のもの使用できます。例えばのstatic final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}代わりにcase 7。したがって、この列挙型の制限は意味がありません(プライマリリテラルだけでなく、手動で定義された定数も整数switch式に使用できますが、手動で定義された定数は使用できませんが、列挙型のプライマリ名しか使用できません)。
Sasha

4

これは行う必要があります:

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        AnotherClass.MyEnum enumExample = AnotherClass.MyEnum.VALUE_A; //...

        switch (enumExample) {
            case VALUE_A: { //<-- error on this line
            //..
            break;
            }
        }
    }
}

あなたはその日を救った!
Soham Mehta


2

これは私がそれを使用している方法です。そしてそれは素晴らしく機能しています-

public enum Button {
        REPORT_ISSUES(0),
        CANCEL_ORDER(1),
        RETURN_ORDER(2);

        private int value;

        Button(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

そしてswitch-case以下に示すように

@Override
public void onClick(MyOrderDetailDelgate.Button button, int position) {
    switch (button) {
        case REPORT_ISSUES: {
            break;
        }
        case CANCEL_ORDER: {
            break;
        }
        case RETURN_ORDER: {
            break;
        }
    }
}

0

someMethod()このように書きます:

public void someMethod() {

    SomeClass.AnotherClass.MyEnum enumExample = SomeClass.AnotherClass.MyEnum.VALUE_A;

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

switchステートメントでは、定数名のみを使用する必要があります。

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