【问题标题】:Mapping magic numbers to enum values, and vice-versa将幻数映射到枚举值,反之亦然
【发布时间】:2014-07-07 07:14:04
【问题描述】:

在我使用它的数据库中,有一些我想映射到State 枚举的幻数,反之亦然。我对undefined.code = 0 的静态声明很感兴趣。如果是这样的话,这个声明实际上是做什么的?

package net.bounceme.dur.data;

public enum State {

    undefined(0), x(1), o(2), c(3), a(4), l(5), d(6);
    private int code = 0;

    static {
        undefined.code = 0;
        x.code = 1;
        o.code = 2;
        c.code = 3;
        a.code = 4;
        l.code = 5;
        d.code = 6;
    }

    State(int code) {
        this.code = code;
    }

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

    public static State getState(int code) {
        for (State state : State.values()) {
            if (state.getCode() == code) {
                return state;
            }
        }
        return undefined;
    }

}

目前这个枚举工厂方法的用法是这样的:

  title.setState(State.getState(resultSet.getInt(5)));

但我会对任何和所有替代方案都感兴趣。

【问题讨论】:

  • 你为什么要这样做?只需将private int code = 0; 更改为private final int code; 并分配一次。 static 块的意义何在?
  • enums 视为具有保证单例属性的常规对象可能会有所帮助。所以code 只是State 对象的一个​​字段,undefined.code 正在访问State 对象的特定实例的该字段。
  • @ElliottFrisch 我不知道静态块的意义是什么,这是我要问的一部分。它用于与我的类似问题中,并且似乎...分配值?
  • 静态块没有任何用途。它做了构造函数已经做的事情。

标签: java enums magic-numbers


【解决方案1】:

我已经删除了无用的静态块并改进了反函数。

public enum State {

private static Map<Integer,State> int2state = new HashMap<>();

undefined(0), x(1), o(2), c(3), a(4), l(5), d(6);
private int code;

State(int code) {   // executed for *each* enum constant
    this.code = code;
    int2state.put( code, this ); 
}

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

public static State getState(int code) {
    return int2state.get(code);
}
}

如果“代码”整数肯定是从 0 开始的序数,则可以省略 Constructor 参数、私有 int 代码和映射,如下所示:

int2state.put( this.ordinal(), this );

【讨论】:

  • 地图是如何填充的?我必须将其打印出来才能查看,但在我看来,似乎地图中只有一个单个条目。它如何拥有所有映射条目?
  • 查看我的第二次编辑 - 对构造函数的评论。这个对每个枚举值执行一次。
  • 构造函数被多次调用,每个枚举实例一次。所以地图是完全填充的。您应该接受这个答案 Thufir,它是正确且有效的。
【解决方案2】:

在您发布的代码中,静态块行

undefined.code = 0;

它访问枚举常量undefined,并盲目地将可变字段code的值从0设置为0。基本上,这里定义了常量

undefined(0)

代码为0x1 也是如此。以此类推。

【讨论】:

    【解决方案3】:

    它确实和构造函数做同样的事情——设置code关联每个枚举值。

    在您的示例中,static { ... } 块是多余的(不必要的)并且可能应该被删除,因为它重复了以 underfined(0) 开头的行。

    Enum 使用变得棘手的地方在于查找(在您的情况下,getState(...) 方法)。这里的case 语句确实第三次重复了代码,您可能最好构建一个Map,它接受一个代码(int)并返回枚举(State) - 只是谷歌周围,有有很多关于如何做到这一点的例子。

    【讨论】:

      【解决方案4】:

      只是一个提示。将您的 getState(int) 方法更改为更具可读性

          public static State getState(int code) {
              for (State state : State.values()) {
                  if (state.getCode() == code) {
                      return state;
                  }
              }
              return undefined; 
          }
      

      【讨论】:

      • @Iaune 对getState(int) 的回答实际上更快更好。
      猜你喜欢
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 2017-11-17
      相关资源
      最近更新 更多