【问题标题】:Java enums and Objective-C enumsJava 枚举和 Objective-C 枚举
【发布时间】:2012-07-11 17:53:21
【问题描述】:

我在 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 语句中的这种枚举:

在 Java 中,您似乎无法为 enum 成员分配索引。我怎样才能获得上述的 Java 等价物?

【问题讨论】:

    标签: java objective-c enums


    【解决方案1】:

    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,不,你不能。如果你指定了一个构造函数,所有枚举项都必须声明它。
    • 不,你不能。序数总是从 0 开始。但是您可以添加一个返回 ordinal() + 1 的方法。
    • 如何使用这个枚举? APIErrorCode(1), APIErrorCode.get(1), APIErrorCode.code(1) ?
    • @JBNizet,我认为鼓励编码器使用序数并不是最好的建议。该序数用于优化旨在替换字节掩码的 EnumSet。
    【解决方案2】:

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

    但是不断发展 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;
        [...]
    }
    

    【讨论】:

    • 谢谢!您的枚举与先前的答案无关!谢谢你这个作品。
    • 不得不说这太疯狂了,这对于 Java 中的枚举来说是多么的矫枉过正,我最好有几个静态变量......
    • @Daniel,很高兴您喜欢这个解决方案。但我会选择 JB Nizet 解决方案。你在哪里打电话case APIErrorOne.getCode():。编译器确保您只切换一种类型,因此无法执行int e = 1 switch { case 1: break; case APIErrorCode: braek; }
    • 但这不起作用,getCode 在你和他的例子中都是实例方法。但我刚刚解决了,我需要这样做:case APIResponseErrorType.EMPTY_FIELD.getCode(): ===> 抱歉,这是我真正的代码。很难理解他的解决方案是如何工作的,但现在我明白了。所以enum 声明比你的要短得多......我想我会切换回他的。谢谢你的解释。
    • @Daniel,你是对的,我忘记了我认为final 可以完成这项工作,但它应该是const,这对于枚举是不可接受的。所以最后,我提供的那个扩展是你问题的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    相关资源
    最近更新 更多