Java枚举和Objective-C枚举

4

我在Objective-C中有以下枚举:

typedef enum {
    APIErrorOne = 1,
    APIErrorTwo,
    APIErrorThree,
    APIErrorFour
} APIErrorCode;

我使用索引来从xml中引用一个枚举,例如,xml可能有error = 2,它映射到APIErrorTwo

我的流程是从xml中获取一个整数,并运行以下switch语句:

int errorCode = 3

switch(errorCode){
    case APIErrorOne:
        //
        break;
    [...]
}

似乎Java不喜欢在switch语句中使用这种类型的枚举:

enter image description here

在Java中,似乎无法为enum成员分配索引。我该如何获得与上述内容等效的Java代码?

2个回答

6

Java中的枚举类型有一个内置的序号(ordinal),第一个枚举成员的序号是0,第二个是1,以此类推。

但枚举类型在Java中也是一种类,因此您也可以为它们分配一个字段:

enum APIErrorCode {
    APIErrorOne(1),
    APIErrorTwo(27),
    APIErrorThree(42),
    APIErrorFour(54);

    private int code;

    private APIErrorCode(int code) {
        this.code = code;
    }

    public int getCode() {
        return this.code;
    }
} 

我能否将第一个错误序号设置为1,而将其他的未分配?就像在Objective-C中一样,索引会级联吗? - Daniel
1
@Daniel,不行。如果你指定了一个构造函数,所有的枚举项都必须声明它。 - Damian Leszczyński - Vash
1
不可以。序数始终从0开始。但是你可以添加一个方法,返回ordinal() + 1。 - JB Nizet
我该如何使用这个枚举?APIErrorCode(1),APIErrorCode.get(1),APIErrorCode.code(1)? - Daniel
2
@JBNizet,我认为鼓励程序员使用序数并不是最好的建议。序数被用来优化EnumSet,它被设计来替换字节掩码。 - Damian Leszczyński - Vash
显示剩余5条评论

3

这里的一般规则是每个帖子只提出一个问题。

但是,JB Nizer的回答在不断发展。

public enum APIErrorCode {

    APIErrorOne(1),
    APIErrorTwo(27),
    APIErrorThree(42),
    APIErrorFour(54);

    private final int code;

    private APIErrorCode(int code) {
        this.code = code;
    }

    public int getCode() {
        return this.code;
    }

    public static APIErrorCode getAPIErrorCodeByCode(int error) {
       if(Util.errorMap.containsKey(error)) {
         return  Util.errorMap.get(error);
       }
       //Or create some default code
       throw new IllegalStateException("Error code not found, code:" + error);
    }

    //We need a inner class because enum are  initialized even before static block
    private static class Util {

        private static final Map<Integer,APIErrorCode> errorMap = new HashMap<Integer,APIErrorCode>();

        static {

            for(APIErrorCode code : APIErrorCode.values()){
                errorMap.put(code.getCode(), code);
            }
        }

    }
}

然后在你的代码中,你可以写:

int errorCode = 3

switch(APIErrorCode.getAPIErrorCodeByCode(errorCode){
    case APIErrorOne:
        //
        break;
    [...]
}

谢谢!你的枚举和之前的答案没有关系!谢谢,这个可行。 - Daniel
不得不说,这对于Java中的枚举来说有些过度设计了,使用几个静态变量可能更好一些... - Daniel
@Daniel,很高兴你喜欢这个解决方案。但我会选择JB Nizet的解决方案,在其中你调用case APIErrorOne.getCode():。编译器确保你只切换一种类型,因此不可能执行int e = 1 switch { case 1: break; case APIErrorCode: braek; } - Damian Leszczyński - Vash
但是那样行不通,你和他的示例中getCode都是实例方法。但我刚刚弄清楚,我需要做:case APIResponseErrorType.EMPTY_FIELD.getCode(): ===> 对不起,这是我的真实代码。很难理解他的解决方案是如何工作的,但现在我可以看到了。所以enum声明比你的要短得多... 我想我会切换回他的方法。感谢您的解释。 - Daniel
1
@Daniel,你说得对,我忘记了,我以为final可以胜任这项工作,但应该是const,而这对于枚举类型是不可接受的。所以最终,我提供的扩展是解决你问题的方案。 - Damian Leszczyński - Vash
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接