enum.values() - is an order of returned enums deterministic
我有一个枚举SOME_ENUM:
1 2 3 4 5
| public enum SOME_ENUM {
EN_ONE,
EN_TWO,
EN_THREE;
} |
SOME_ENUM.values()将始终按枚举声明的顺序返回枚举:
EN_ONE, EN_TWO, EN_THREE? 是规则还是不能保证在下一个JDK版本中不会更改它?
-
我遍历我的枚举以填充一个列表,而不是在我遍历该枚举的代码中的其他位置。
-
@MitchWheat出于同样的原因,您将依赖于List的保留顺序:因为JDK是一种为您提供一定保证的工具,而依靠这些保证可以帮助您编写更简洁,更好的代码。 诚然,问题"是否保证不会更改?" 无法回答,您当然不能依靠它,没有什么可以保证。
Java语言规范使用以下显式语言:
@return an array containing the constants of this enum type, in the order they're declared [Source]
因此,是的,它们将按声明顺序返回。值得注意的是,如果有人更改课程,顺序可能会随着时间而改变,因此请务必谨慎使用。
-
如果有人在以后的代码版本中在中间添加一个值,这可能会使您不知所措,因为这会更改其他元素的顺序值(请参见Enum.ordinal())方法。因此,最好不要将序数位置作为序列化机制(即,不要将其存储在数据库中)。
-
链接到该规范的来源?
-
Java 8文档
是的,保证按此顺序返回它们。
但是,您应该避免依赖于ordinal()值,因为例如在插入新项目后它可能会更改。
-
+1为贤哲建议。关于ordinal()主题,Effective Java建议将成员字段添加到枚举类型。
它由声明值的顺序决定。但是,不能保证您(或其他人)将来不会重新排序/插入/删除值。因此,您不应该依赖订单。
有效的Java 2。 Edition将其第31项专用于一个紧密相关的主题:使用实例字段代替普通字段:
Never derive a value associated with an enum from its ordinal; store it in an instance field instead.
-
"不保证某人将来不会对值进行重新排序"-但这正是我要依赖该命令的原因:-)!我希望将来能够重新订购商品,从而改变程序的行为。 Bloch对不依赖序数是正确的,如果发问者的示例确实涉及EN_TWO之类的枚举,那么他就是在依赖序数,因此不应该这样做。但是依靠顺序是完全可以的。实际上,为了保证顺序,创建专门用于顺序的字段将编写冗余代码,像有效Java这样的事情书告诉您不要这样做。
-
@Fletch,对不起,我不太了解您。对我来说,这听起来像是您出于某些目的而尝试使用enum。
-
假设您有著名的"行星"枚举。在您的用户界面中,您要按照行星到太阳的距离顺序列出它们。您如何最好地做到这一点?我将以正确的顺序在enum类中对行星常量进行排序,然后仅在UI中枚举枚举。由于顺序是可靠的,因此可以使用。那就是我在说的那种话。如果有一天地球比火星更靠近太阳,那么当然,在这样的时刻,您热情的第一件事就是维护您的代码!因此,您要上行星课,然后将地球移到火星之前。
-
@Fletch,地球已经比火星更靠近太阳了;-)但是我明白你的意思了。但是,在这种情况下,行星的顺序实际上是它们与太阳的平均距离的函数,这不是简单的序数,因此恕我直言,最好将其存储为每个行星的不同场。然后,您可以让一个琐碎的比较器根据它们与太阳的平均距离比较行星,并使用此比较器对其进行排序。恕我直言,这是一种干净,简单的解决方案。而您的解决方案会在例如一个新同事决定,显然应该按字母顺序列出行星;-)
-
哈哈哈嗯,好吧,反正都是阴谋,没有火星。最初我打算使用土星,但不记得它在哪颗行星附近,但火星计划似乎事与愿违:-)。无论如何...在这种情况下,比较器会很好,但是显然需要更多代码。我认为,如果您依赖于源代码排序,那么在类注释中进行记录将是一件好事。您的同事甚至可以阅读。
-
@Fletch,确实,有经过验证的开发人员实际上正在阅读Javadoc的案例……即使我已经做到了:-)恕我直言,代码量的差异不是那么大(如果Java具有更多的功能,那会很小),但是,这就是我们必须忍受的东西。
其他答案很好,但是不要对此发表评论:
"Is it a rule or it is not guaranteed to be not changed in the next
Jdk releases?"
我不相信将来的JDK存在保证,因此您甚至不必担心它们。没有办法执行它们,将来的JDK领导可能会决定放弃这种保证。就像威斯敏斯特议会制一样:"没有议会可以约束未来的议会。"
就是说,JDK的历史揭示了极好的一致性。它们并没有进行很多重大更改,因此您可以确信将保留当前指定的(不仅仅是观察到的)行为。