enum.values() - is an order of returned enums deterministic
Asked Answered
F

5

110

I have a enum SOME_ENUM:

public enum SOME_ENUM {
  EN_ONE,
  EN_TWO,
  EN_THREE;
}

Will SOME_ENUM.values() always return the enums in the order of enum declarations: EN_ONE, EN_TWO, EN_THREE? Is it a rule or it is not guaranteed to be not changed in the next JDK releases?

Fannyfanon answered 29/9, 2010 at 9:1 Comment(2)
I iterate over my enum to fill a list, which than in other place in the code I read iterating over this enum.Fannyfanon
@MitchWheat For the same reason that you would rely on a List preserving order: because the JDK is a tool which gives you certain guarantees and relying on these guarantees helps you to write more succinct and better code. Admittedly, the question "Is it guaranteed not to be changed?" is impossible to answer, you certainly can't rely on that, nothing has that guarantee.Parasang
W
148

The Java language specification uses this explicit language:

@return an array containing the constants of this enum type, in the order they're declared [Source]

So, yes, they will be returned in declaration order. It's worth noting that the order might change over time if someone changes the class so be very careful about how you use this.

Wolfgang answered 29/9, 2010 at 9:8 Comment(3)
If someone adds a value in the middle in a later code version, this could hose you up, as it would change the ordinal value of other elements (see the Enum.ordinal()) method. It's best not to rely on the ordinal position as a serialization mechanism (ie, don't store it in the db) for this reason.Spears
Link to the source for that specification?Rica
Java 8 docOtalgia
S
17

Yes, it is a guaranteed to return them in that order.

However you should avoid relying on that, and on the ordinal() value, since it can change after inserting new items, for example.

Sepal answered 29/9, 2010 at 9:7 Comment(1)
+1 for the sage advice. On the topic of ordinal(), Effective Java suggests adding a member field to the enum type.Commonable
S
9

It is determined by the order your values are declared in. However, there is no guarantee that you (or someone else) won't reorder / insert / remove values in the future. So you shouldn't rely on the order.

Effective Java 2nd. Edition dedicates its Item 31 to a closely related topic: Use instance fields instead of ordinals:

Never derive a value associated with an enum from its ordinal; store it in an instance field instead.

Samathasamau answered 29/9, 2010 at 9:7 Comment(6)
"no guarantee that someone won't reorder values in the future" - but that's exactly why I want to rely on the order :-)! I want to be able to re-order the items in future and thereby change the behaviour of my program. Bloch is right about not relying on the ordinal and if the asker's example really involves enums like EN_TWO then he is relying on the ordinal and shouldn't do this. But to rely on the order is perfectly fine. In fact, as order is guaranteed, to create a field specifically for order would be writing redundant code, the kind of thing books like Effective Java tell you not to do.Parasang
@Fletch, sorry, I don't quite follow you. To me this sounds like you are trying to use enum for some purpose it was not intended for.Slippery
let's say you have the famous "Planet" enum. In your UI you want to list the planets in the order of their distance from the sun. How can you best acheive this? I would order the planet constants in the correct order inside the enum class and then just enumerate the enum in the UI. Since the order is dependable this will work. That's the kind of thing I'm talking about. If one day Earth moves closer to the sun than Mars, of course in such a moment the first thing on your warm mind will be maintaining your code! So you go to your Planet class and move EARTH to before MARS.Parasang
@Fletch, Earth is already closer to Sun than Mars ;-) but I get what you mean. However, in this case the order of planets is actually a function of their mean distance from Sun, which is not a simple ordinal, thus IMHO it should better be stored as a distinct field for each planet. Then you can have a trivial comparator compare planets based on their mean distance from Sun, and order them using this comparator. This is IMHO a clean and foolproof solution. Whereas your solution breaks as soon as e.g. a new colleague decides that planets should obviously be listed in alphabetic order ;-)Slippery
Hahaha ermm yes well anyway it's all a conspiracy, there is no Mars. Initially I was going to use Saturn but couldn't remember which planets it is near, but the Mars plan seems to have backfired :-). Anyway... in this case a comparitor would be good but has the downside of requiring more code, obviously. I think that if you are relying on the source code ordering, documenting this in the class comments would be a good thing. Your colleague might even read it.Parasang
@Fletch, indeed, there are proven cases of developers actually reading Javadoc... even I have done it :-) IMHO the difference in amount of code is not that big (would be quite tiny if Java had more functional capabilities, but alas, this is what we got to live with).Slippery
P
7

The other answers are good, but don't comment on this:

"Is it a rule or it is not guaranteed to be not changed in the next Jdk releases?"

I don't believe that guarantees on future JDKs exist, so you shouldn't even worry about them. There would be no way to enforce them, future JDK leads might just decide to reneg on such guarantees. It's like the Westminster system of parliament: "No Parliament can bind a future parliament."

That said, the history of the JDK reveals excellent consistency. They don't make a lot of breaking changes, so you can be pretty confident that current specified (not just observed) behaviour will be preserved.

Parasang answered 13/8, 2012 at 12:5 Comment(0)
C
0

To add on top of GaryF answer.

Yes the order is guaranty by the Java. However...

Obfuscation can break it. So be very carful with it

Characteristically answered 26/7, 2023 at 17:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.