2011-03-21 337 views

回答

58

你不能设置它。它始终是不变定义的序数。看到documentation for Enum.ordinal()

返回枚举常数的序(它在枚举声明,其中初始常量被分配的零序位置)。大多数程序员将无法使用这种方法。它设计用于复杂的基于枚举的数据结构,如EnumSet和EnumMap。

实际上 - 你不应该需要。如果你想要一些整数属性,请定义一个。

+5

如果我可以指定枚举的顺序,当使用JPA用枚举,那将是更安全... – 2011-03-21 14:18:41

75

您可以通过更改枚举的顺序来控制序号,但不能像C++那样显式设置它。一个解决办法是你想要的号码提供额外的方法,在您的枚举:

enum Foo { 
    BAR(3), 
    BAZ(5); 
    private final int val; 
    private Foo(int v) { val = v; } 
    public int getVal() { return val; } 
} 

在这种情况下BAR.ordinal() == 0,但BAR.getVal() == 3

+7

+1除了这个ISN真的是一种解决方法。这是理想的行为。序数值被认为是实现人工产物;如果你想分配一个整数或其他值,这就是“枚举是clases”是如此之大... – andersoj 2011-03-21 01:43:24

+1

wouldnt BAR.ordinal()返回0 afaik枚举索引是零基于 – Terraego 2012-03-10 14:59:41

+0

@Terraego良好的捕获。 – Matt 2012-03-14 04:33:42

2

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Enum.html

公共最终诠释序()返回此枚举常数的序(它在枚举声明,其中初始常量被分配的零序位置)。大多数程序员将无法使用这种方法。它设计用于复杂的基于枚举的数据结构,如EnumSet和EnumMap。

返回: 枚举常量的序

如果你有

公共枚举日{ 周日,周一,周二,周三, 周四,周五,周六 }

然后SUNDAY的序数为0,MONDAY为1,依此类推...

+3

不能保证上面的顺序! – claj 2014-01-10 14:02:44

+1

@claj,你可以扩展一下吗?文件似乎表明它确实如此。 – Celos 2014-08-26 13:01:49

+0

对不起@Celos,第一枚枚举的确是0,但规范并没有提到除了单调递增之外应如何赋值。我认为我在Effective Java等方面阅读了一些关于此警告的内容,但不要听我的话。 – claj 2014-08-26 13:55:53

0

检查出的Java Enum examplesdocs

返回枚举常数的序(它在枚举声明,其中初始常量被分配的零序位置)。大多数程序员将无法使用这种方法。它设计用于复杂的基于枚举的数据结构,如EnumSet和EnumMap。

-2

简单的答案:只是改变常量的顺序。第一个定义为0,第二个定义为1,等等。但是,如果你经常更改代码,或者枚举会有许多值,这可能不太实际。您可以定义一个自定义方法来解决默认序号问题,但请确保它有充分的文档记录以避免混淆!

public enum Values 
{ 
    ONE, TWO, THREE, FOUR; 

    public int getCustomOrdinal() 
    { 
     if(this == ONE) 
     { 
      return 3; 
     } 
     else if(this == TWO) 
     { 
      return 0; 
     } 
     ... 
    } 
} 
+4

+1:switch语句可能比一系列if-else语句更好。 – 2011-03-21 07:44:00

+4

我不喜欢这个解决方案。枚举是类,因此可以包含自定义属性。我宁愿为这个和相应的getter方法定义一个字段。 – Atmocreations 2014-05-21 09:04:04

+0

这是一般较好的解决方案。但问题是否有可能改变ordinal()的行为... – donnyton 2014-09-05 20:46:58

4

您可以使用反射更新序号:

private void setEnumOrdinal(Enum object, int ordinal) { 
    Field field; 
    try { 
     field = object.getClass().getSuperclass().getDeclaredField("ordinal"); 
     field.setAccessible(true); 
     field.set(object, ordinal); 
    } catch (Exception ex) { 
     throw new RuntimeException("Can't update enum ordinal: " + ex); 
    } 
} 
1

由于接受的答案指出,你不能设置序号。你可以得到这个最接近的是自定义属性

public enum MonthEnum { 

    JANUARY(1), 
    FEBRUARY(2), 
    MARCH(3), 
    APRIL(4), 
    MAY(5), 
    JUNE(6), 
    JULY(7), 
    AUGUST(8), 
    SEPTEMBER(9), 
    OCTOBER(10), 
    NOVEMBER(11), 
    DECEMBER(12); 

    MonthEnum(int monthOfYear) { 
     this.monthOfYear = monthOfYear; 
    } 

    private int monthOfYear; 

    public int asMonthOfYear() { 
     return monthOfYear; 
    } 

}