Java: การใช้คำสั่ง switch กับ enum ภายใต้คลาสย่อย


265

ก่อนอื่นฉันจะระบุว่าฉันคุ้นเคยกับ enums ใน C # มากขึ้นและดูเหมือนว่า enums ใน java นั้นค่อนข้างยุ่ง

อย่างที่คุณเห็นฉันกำลังพยายามใช้ switch statement @ enums ในตัวอย่างถัดไปของฉัน แต่ฉันได้รับข้อผิดพลาดเสมอไม่ว่าฉันจะทำอะไร

ข้อผิดพลาดที่ฉันได้รับคือ:

SomeClass.AnotherClass.MyEnum.VALUE_Aต้องเปลี่ยนฉลากเคสที่ผ่านการรับรองด้วยค่าคงที่ enum ที่ไม่มีเงื่อนไขVALUE_A

สิ่งนี้คือฉันค่อนข้างเข้าใจถึงข้อผิดพลาด แต่ฉันไม่สามารถเขียน VALUE_A ได้เนื่องจาก enum ตั้งอยู่ในคลาสย่อยอื่น มีวิธีแก้ไขปัญหานี้หรือไม่? แล้วทำไมมันถึงเกิดขึ้นใน 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มีประโยชน์มากเมื่อคุณได้รับของพวกเขา - ไม่ยุ่งเลย พวกมันมีความยืดหยุ่นและใช้งานได้จริงมากกว่า enums ง่าย ๆ (เพียงแค่ค่าจำนวนเต็มที่มีป้ายกำกับ) ตามที่เห็นบนแพลตฟอร์มอื่น ๆ ดูออราเคิลกวดวิชา ค้นพบการเพิ่มประสิทธิภาพSet/ การใช้งาน:Map & EnumSetEnumMap
Basil Bourque

1
เมื่อคุณพยายามที่จะมีคุณสมบัติคำสั่งกรณี คุณกำลังพยายามบอกว่าฉันสามารถผสม enums ประเภทต่างๆ (ไม่ใช่แค่ enum ประเภทเดียวกัน) ภายในคำสั่ง switch เดียว Java ได้หยุดมันด้วยวิธีนี้ตามที่กล่าวไว้ที่นี่digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal

เรื่องนี้เกิดขึ้นกับฉันในขณะที่การสร้างใหม่ (ย้าย) ชั้นเรียนใน IntelliJ 2018.2
Daniel Alder

คำตอบ:


570

เปลี่ยนเป็น:

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

เบาะแสอยู่ในข้อผิดพลาด คุณไม่จำเป็นต้องมีสิทธิ์ได้รับcaseฉลากด้วยประเภท enum เพียงมูลค่าของมัน


20
ตกลงฉันรู้สึกโง่ดังนั้น :-( คุณมีทั้งหมดขวาฉันเชื่อว่าฉันพยายามบรรทัดนี้แน่นอนและมีข้อผิดพลาดกับที่ดังนั้นผมจึงย้ายที่จะมีคุณสมบัติกรณี แต่คำแนะนำของคุณไม่ทำงาน.
Popokoko

4
โดยวิธีการที่ฉันคิดว่าคุณจะพบว่าใน enums Java มีประโยชน์อย่างไม่น่าเชื่อเมื่อคุณเริ่มต้นการใช้พวกเขามากขึ้นผมจะไม่บอกว่าพวกเขากำลังเป็นระเบียบที่ :) ทั้งหมด
darrengorman

11
@milkplusvellocet ฉันรู้ว่าโพสต์นี้เก่าแล้ว แต่ฉันอยากรู้ว่าทำไม Java ไม่อนุญาตให้ติดฉลากเคสที่มีคุณสมบัติในคำสั่ง switch?
jzarsuelo

3
@ cRane01 ไม่ทราบแน่ชัด แต่สร้างมาเพื่อไวยากรณ์ที่สะอาดกว่า การระบุประเภทในแต่ละกรณีจะซ้ำซ้อนกันโดยสิ้นเชิง
darrengorman

3
@HelloGoodbye ไม่ตัวแปรของคำสั่ง switch กำหนดประเภทของคำสั่ง case เพื่อให้สามารถเป็น enum ได้เพียงรายการเดียว
วิ่งแข่ง

33

Java infers อัตโนมัติประเภทขององค์ประกอบใน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ørn Ravn Andersen

11
หากคุณมีคุณสมบัติคุณควรใช้อย่างอื่นMyEnumที่ไม่สมเหตุสมผล
ครู

1
@ ครู แต่ฉันสามารถใช้บางสิ่งบางอย่างทางไวยากรณ์สำหรับการแสดงออกกรณีที่ไม่ได้พิมพ์ enum เช่นแทนstatic final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;} case 7ดังนั้นข้อ จำกัด นี้สำหรับ enums จึงไม่มีเหตุผล (ฉันสามารถใช้ตัวอักษรหลักไม่เพียง แต่ยังคงค่าคงที่ที่กำหนดด้วยตนเองสำหรับswitchนิพจน์จำนวนเต็มแต่ฉันไม่สามารถใช้ค่าคงที่ที่กำหนดด้วยตนเอง แต่ใช้ชื่อหลักสำหรับ enums เท่านั้น)
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

3

ไม่ถูกต้อง:

case AnotherClass.MyEnum.VALUE_A

ขวา:

case VALUE_A:

1
ฉันยกระดับคุณเพราะเห็นได้ชัดว่าปัญหาคืออะไร
joaorodr84

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;
    }

}

ในคำสั่งสลับคุณต้องใช้ชื่อคงที่เท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.