【问题标题】:Storing integer values as constants in Enum manner in java [duplicate]在java中以枚举方式将整数值存储为常量[重复]
【发布时间】:2011-04-28 18:23:55
【问题描述】:

我目前正在以下列方式创建整数常量。

public class Constants {
    public static int SIGN_CREATE=0;
    public static int SIGN_CREATE=1;
    public static int HOME_SCREEN=2;
    public static int REGISTER_SCREEN=3;
}

当我尝试以枚举方式执行此操作时

public enum PAGE{SIGN_CREATE,SIGN_CREATE,HOME_SCREEN,REGISTER_SCREEN}

当我使用PAGE.SIGN_CREATE 时,它应该返回 1;

【问题讨论】:

  • 那不会编译;您已经定义了两次“SIGN_CREATE”。此外,这些不是常量——它们不是“最终的”。

标签: java enums constants


【解决方案1】:

您可以使用ordinal。所以PAGE.SIGN_CREATE.ordinal() 返回1

编辑:

这样做的唯一问题是,如果您添加、删除或重新排序枚举值,您将破坏系统。对于许多人来说,这不是问题,因为他们不会删除枚举,只会在末尾添加额外的值。它也不比整数常量差,整数常量也需要你不要重新编号。但是最好使用如下系统:

public enum PAGE{
  SIGN_CREATE0(0), SIGN_CREATE(1) ,HOME_SCREEN(2), REGISTER_SCREEN(3)

  private int id;

  PAGE(int id){
    this.id = id;
  }

  public int getID(){
    return id;
  }

}

然后您可以使用getID。所以PAGE.SIGN_CREATE.getID() 返回1

【讨论】:

  • 虽然是个坏主意,因为它会随着类声明中常量的顺序发生变化而改变。
  • @Michael - 这是一个很好的观点。我添加了一个额外的方法来避免这个问题。
【解决方案2】:

您可以像这样将该 const 值存储在枚举中。但是为什么还要使用 const 呢?你在坚持枚举吗?

public class SO3990319 {
   public static enum PAGE {
      SIGN_CREATE(1);
      private final int constValue;

      private PAGE(int constValue) {
         this.constValue = constValue;
      }

      public int constValue() {
         return constValue;
      }
   }

   public static void main(String[] args) {
      System.out.println("Name:    " + PAGE.SIGN_CREATE.name());
      System.out.println("Ordinal: " + PAGE.SIGN_CREATE.ordinal());
      System.out.println("Const:   " + PAGE.SIGN_CREATE.constValue());

      System.out.println("Enum: " + PAGE.valueOf("SIGN_CREATE"));
   }
}

编辑:

这取决于您使用 int 是使用 EnumMap 还是实例字段。

【讨论】:

  • 我面临无法通过枚举值来切换大小写的问题! “case Actions.CREATE.getAction()”它给出一个错误“case 表达式必须是常量表达式”
  • Actions.CREATE 是枚举。 #getAction() 不是...
【解决方案3】:

好吧,你不能那样做。 PAGE.SIGN_CREATE 永远不会返回 1;它将返回PAGE.SIGN_CREATE。这就是枚举类型的意义所在。

但是,如果您愿意添加一些击键,您可以向枚举添加字段,如下所示:


    public enum PAGE{
        SIGN_CREATE(0),
        SIGN_CREATE_BONUS(1),
        HOME_SCREEN(2),
        REGISTER_SCREEN(3);

        private final int value;

        PAGE(final int newValue) {
            value = newValue;
        }

        public int getValue() { return value; }
    }

然后你调用PAGE.SIGN_CREATE.getValue()得到0。

【讨论】:

  • 这其实不是真的。你可以做 PAGE.SIGN_CREATE.ordinal()。这将返回 0。可能此 anwser 与尚未具有此功能的 java 版本有关。
  • 你们想在一个枚举中混合数字和字符吗?例如。如果我想要一个枚举来存储 0、1 和 X?谢谢!!
  • @BlairHippo:我可以做类似PAGE pageEnum = PAGE(0) 的事情吗?简而言之,我有一个值,我想获得具有选定值的相应枚举。你能回答吗?
  • 你会如何在 switch 语句中使用这个枚举?
  • @Pierre 你找到解决办法了吗?我也遇到了同样的要求,谢谢
【解决方案4】:

想要与每个枚举值关联的整数常量最常见的正当理由是与其他仍然需要这些整数的组件进行互操作(例如,您无法更改的序列化协议,或者枚举表示表中的列等)。

在几乎所有情况下,我都建议改用EnumMap。它更完全地解耦了组件,如果这是关注点,或者如果枚举表示列索引或类似的东西,您可以在以后轻松地进行更改(如果需要,甚至在运行时)。

 private final EnumMap<Page, Integer> pageIndexes = new EnumMap<Page, Integer>(Page.class);
 pageIndexes.put(Page.SIGN_CREATE, 1);
 //etc., ...

 int createIndex = pageIndexes.get(Page.SIGN_CREATE);

它通常也非常高效。

将这样的数据添加到枚举实例本身可能非常强大,但经常被滥用。

编辑:刚刚意识到 Bloch 在 Effective Java / 第 2 版中的第 33 条:使用 EnumMap 而不是序数索引中解决了这个问题。

【讨论】:

  • EnumMap 推荐+1。
  • 这也很冗长。这意味着您保留一个完全独立的数据结构,只是为了拥有从键到派生数字索引的映射。 Bloch 还(第 31 项)建议简单的整数索引值使用@BlairHippo 对这个问题的回答中概述的模式。
【解决方案5】:

如果您希望能够将 integer 转换回对应的 enum 并使用选定的值,请参阅下面的自动生成代码中的 Constants.forValue(...),但如果不是,BlairHippo 的答案是最好的方法去做吧。

public enum Constants
{
SIGN_CREATE(0),
SIGN_CREATE(1),
HOME_SCREEN(2),
REGISTER_SCREEN(3);

    public static final int SIZE = java.lang.Integer.SIZE;

    private int intValue;
    private static java.util.HashMap<Integer, Constants> mappings;
    private static java.util.HashMap<Integer, Constants> getMappings()
    {
        if (mappings == null)
        {
            synchronized (Constants.class)
            {
                if (mappings == null)
                {
                    mappings = new java.util.HashMap<Integer, Constants>();
                }
            }
        }
        return mappings;
    }

    private Constants(int value)
    {
        intValue = value;
        getMappings().put(value, this);
    }

    public int getValue()
    {
        return intValue;
    }

    public static Constants forValue(int value)
    {
        return getMappings().get(value);
    }
}

【讨论】:

    【解决方案6】:

    我发现这很有帮助:

    http://dan.clarke.name/2011/07/enum-in-java-with-int-conversion/

    public enum Difficulty
    {
        EASY(0),
        MEDIUM(1),
        HARD(2);
    
        /**
        * Value for this difficulty
        */
        public final int Value;
    
        private Difficulty(int value)
        {
            Value = value;
        }
    
        // Mapping difficulty to difficulty id
        private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>();
        static
        {
            for (Difficulty difficulty : Difficulty.values())
                _map.put(difficulty.Value, difficulty);
        }
    
        /**
        * Get difficulty from value
        * @param value Value
        * @return Difficulty
        */
        public static Difficulty from(int value)
        {
            return _map.get(value);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 2019-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多