Java: sử dụng câu lệnh switch với enum dưới lớp con


265

Đầu tiên tôi sẽ nói rằng tôi quen thuộc hơn với các enum trong C # và có vẻ như các enum trong java là một mớ hỗn độn.

Như bạn có thể thấy, tôi đang cố gắng sử dụng câu lệnh switch @ enums trong ví dụ tiếp theo của mình nhưng tôi luôn gặp lỗi bất kể tôi đang làm gì.

Lỗi tôi nhận được là:

Nhãn trường hợp đủ điều kiện SomeClass.AnotherClass.MyEnum.VALUE_Aphải được thay thế bằng hằng số enum không đủ tiêu chuẩnVALUE_A

Vấn đề là tôi khá hiểu lỗi nhưng tôi không thể viết VALUE_A vì enum nằm trong một lớp con khác. Có cách nào để giải quyết vấn đề này? Và tại sao nó lại xảy ra trong 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;
            }
        }
    }
}

Như darrengorman nhận xét, Java Enumvô cùng tiện dụng khi bạn nhận được hang của họ - không phải ở tất cả một mớ hỗn độn. Chúng linh hoạt và thực tế hơn nhiều so với các enum đơn giản (chỉ đơn thuần là một giá trị số nguyên được gắn nhãn) như đã thấy trên các nền tảng khác. Xem Hướng dẫn của Oracle . Khám phá các tối ưu hóa Set/ Maptriển khai: EnumSet& EnumMap.
Basil Bourque

1
Khi bạn cố gắng để đủ điều kiện tuyên bố trường hợp; theo một cách nào đó, bạn đang cố gắng nói rằng tôi có thể trộn các loại enum khác nhau (không chỉ cùng loại enum) trong một câu lệnh chuyển đổi. Java đã ngừng nó với phương pháp này như đã thảo luận ở đây digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal

Điều này đã xảy ra với tôi khi tái cấu trúc (di chuyển) một lớp học trong IntelliJ 2018.2
Daniel Alder

Câu trả lời:


570

Thay đổi nó thành này:

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

Manh mối là trong lỗi. Bạn không cần phải đủ điều kiện casenhãn với loại enum, chỉ giá trị của nó.


20
Ok tôi cảm thấy thật ngu ngốc :-( Bạn hoàn toàn đúng, tôi tin rằng tôi đã thử dòng chính xác này và đã gặp lỗi với nó vì vậy tôi đã chuyển sang trường hợp đủ điều kiện, nhưng đề nghị của bạn KHÔNG hoạt động.
Popokoko

4
Theo cách tôi nghĩ, bạn sẽ thấy rằng enum trong Java cực kỳ hữu ích một khi bạn bắt đầu sử dụng chúng nhiều hơn, tôi sẽ không nói chúng là một mớ hỗn độn :)
darrengorman

11
@milkplusvellocet, tôi biết bài đăng này đã cũ, nhưng tôi tò mò tại sao Java không cho phép nhãn trường hợp đủ điều kiện trong câu lệnh chuyển đổi?
jzarsuelo

3
@ cRane01 không biết chắc chắn, nhưng nó làm cho cú pháp sạch hơn. Chỉ định loại trên mỗi trường hợp sẽ hoàn toàn dư thừa
darrengorman

3
@Hellooodbye Không. Biến của câu lệnh switch xác định loại câu lệnh tình huống để nó chỉ có thể là một enum.
người chạy nước rút

33

Java tự động nhập loại phần tử trong case, vì vậy các nhãn phải không đủ tiêu chuẩn.

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

14
Tại sao phải nó được không đủ tiêu chuẩn?
Thorbjørn Ravn Andersen

11
Nếu bạn có thể đủ điều kiện, thì bạn có thể sử dụng một cái gì đó khác hơn là MyEnumkhông có ý nghĩa.
Kru

1
@Kru, nhưng tôi có thể sử dụng một cái gì đó về mặt ngữ pháp cho các biểu thức trường hợp không được gõ. Ví dụ static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}thay vì case 7. Vì vậy, hạn chế này cho enums làm cho không có ý nghĩa (Tôi có thể sử dụng không chỉ literals tiểu học, nhưng hằng cũng tự xác định cho số nguyên switchbiểu hiện, nhưng tôi không thể sử dụng hằng số bằng tay được xác định, nhưng tên chỉ chính cho sự đếm).
Sasha

4

điều này nên làm:

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

Bạn đã tiết kiệm trong ngày!
Soham Mehta

3

Sai lầm:

case AnotherClass.MyEnum.VALUE_A

Đúng:

case VALUE_A:

1
Tôi ủng hộ bạn vì nó rõ ràng hơn về vấn đề là gì.
joaorodr84

2

Đây là cách tôi đang sử dụng nó. Và nó đang hoạt động rất tuyệt vời -

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-casenhư hình dưới đây

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

0

Viết someMethod()theo cách này:

public void someMethod() {

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

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

Trong câu lệnh switch, bạn phải sử dụng tên hằng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.