Java 5.0 Enum: why not valueOf(int ordinal)?

D

diegomrosa

Hi all,

is there any reason to have a method valueOf(Class<T> enumType, String
name) in the Java 5.0 class Enum and not have a valueOf(Class<T>
enumType, int ordinal)?

Which is the right form to get an Enum from its ordinal? I have found
some discussion on this, but not good explanations.

Thanx in advance,
Diego
 
C

Chris Uppal

diegomrosa said:
is there any reason to have a method valueOf(Class<T> enumType, String
name) in the Java 5.0 class Enum and not have a valueOf(Class<T>
enumType, int ordinal)?

Probably because enums are intended to be, and to be treated as, /objects/
rather than as glossy syntax for integers (as in C).

Which is the right form to get an Enum from its ordinal?

Why do you need the ordinal ? I know there are some circumstances where you
might need it, but I imagine that they are rare.

If you do need it, for whatever reason, then you could use the enum class's
static values() method to find and loop over the enum's instances. For each one
put the instance into an array indexed by its ordinal(). Or use the enum's
Class object's getEnumConstants() to do the same thing.

-- chris
 
D

David Hume

diegomrosa said:
Hi all,

is there any reason to have a method valueOf(Class<T> enumType, String
name) in the Java 5.0 class Enum and not have a valueOf(Class<T>
enumType, int ordinal)?
If the enum definition is later modified, then the ordinals may change,
as they are based on the ordering of the values. For example:

enum Ints {
ZERO, // gets ordinal = 0
ONE, // gets ordinal = 1
TWO, // gets ordinal = 2
THREE, // gets ordinal = 3
FOUR; // gets ordinal = 4
}

If you later changed the enum, and in a moment of madness did this:

enum Ints {
MINUSONE, // gets ordinal = 0
ZERO, // gets ordinal = 1
ONE, // gets ordinal = 2
TWO, // gets ordinal = 3
THREE, // gets ordinal = 4
FOUR;// gets ordinal = 5
}

If you had stored information on the enum based on the ordinal (say
writing ordinal values to a file for later rereading) then these values
would correspond to the wrong enums when reloaded. On the other hand,
had you used the string values, all would be well. If you *know* that
your enum is never going to change, using the ordinal may be suitable.
If you do have to add values later, just make sure to put them at the
end.
I haven't checked, but I assume this is how the built in Serialisation
does things.
Which is the right form to get an Enum from its ordinal? I have found
some discussion on this, but not good explanations.

Thanx in advance,
Diego

If you are sure your enum won't change, or that values will only be
added to the end, then a static method such as:

enum Ints {
ZERO,ONE,TWO,THREE,FOUR;

public static Ints fromOrd(int i) {
if (i < 0 || i >= Ints.values().length) {
throw IndexOutOfBoundsException("Invalid ordinal");
}
return Ints.values();
}
}

might work. Alternatively you can build you own ordinal system that
can use values you define, although it's a bit of a PITA:

enum Ints {
ZERO(0),
ONE(1),
TWO(2),
THREE(3),
FOUR(4);

private final int _ord;

Ints(int i) {
_ord = i;
}

int getOrd() { return _ord; }
}

-Dave
 
R

Roedy Green

Which is the right form to get an Enum from its ordinal? I have found
some discussion on this, but not good explanations.

public int ordinal();
// tells you where in the order this enum constant fits, first one is
0.
// The compiler automatically generates an ordinal field in each
object
// telling it where it belongs in the order.

The puzzle is this method is GENERATED. You won't find it in the Enum
base class.
 
D

diegomrosa

If you had stored information on the enum based on the ordinal (say
writing ordinal values to a file for later rereading) then these values
would correspond to the wrong enums when reloaded. On the other hand,
had you used the string values, all would be well. If you *know* that
your enum is never going to change, using the ordinal may be suitable.
If you do have to add values later, just make sure to put them at the
end.

maybe the right question would be: "how to safely/efficiently store
enum values?". Well, I dont know about the rest of you, but I need to
persist enum values all the time!

The obvious way to store an enum value seems to be using its ordinal
(at least to me!). Storing the string values would be a lot more
expensive and not a bit more secure. You are right in saying that
storing the ordinal could be dangerous in case you change the enum
order. However, storing the string value would prohibit the user
changing the name of the enum constants. Both cases seem remote to me,
but I would consider changing a enum value name even more common than
changing its order. That is why my surprise that class Enum has a
method to convert a string into an enum but not an equivalent to
convert an ordinal into an enum.

Ok, I can write a method somewhere to convert an ordinal into an enum,
but where should I put it?!? Well, the Enum class seems to be the
obvious choice.
If you are sure your enum won't change, or that values will only be
added to the end, then a static method such as:

enum Ints {
ZERO,ONE,TWO,THREE,FOUR;

public static Ints fromOrd(int i) {
if (i < 0 || i >= Ints.values().length) {
throw IndexOutOfBoundsException("Invalid ordinal");
}
return Ints.values();
}
}


this means I have to duplicate this code on every Enum. Frustrating!
might work. Alternatively you can build you own ordinal system that
can use values you define, although it's a bit of a PITA:

enum Ints {
ZERO(0),
ONE(1),
TWO(2),
THREE(3),
FOUR(4);

private final int _ord;

Ints(int i) {
_ord = i;
}

int getOrd() { return _ord; }
}

More frustrating!

Diego
 
W

Wibble

diegomrosa said:
If you had stored information on the enum based on the ordinal (say
writing ordinal values to a file for later rereading) then these values
would correspond to the wrong enums when reloaded. On the other hand,
had you used the string values, all would be well. If you *know* that
your enum is never going to change, using the ordinal may be suitable.
If you do have to add values later, just make sure to put them at the
end.


maybe the right question would be: "how to safely/efficiently store
enum values?". Well, I dont know about the rest of you, but I need to
persist enum values all the time!

The obvious way to store an enum value seems to be using its ordinal
(at least to me!). Storing the string values would be a lot more
expensive and not a bit more secure. You are right in saying that
storing the ordinal could be dangerous in case you change the enum
order. However, storing the string value would prohibit the user
changing the name of the enum constants. Both cases seem remote to me,
but I would consider changing a enum value name even more common than
changing its order. That is why my surprise that class Enum has a
method to convert a string into an enum but not an equivalent to
convert an ordinal into an enum.

Ok, I can write a method somewhere to convert an ordinal into an enum,
but where should I put it?!? Well, the Enum class seems to be the
obvious choice.

If you are sure your enum won't change, or that values will only be
added to the end, then a static method such as:

enum Ints {
ZERO,ONE,TWO,THREE,FOUR;

public static Ints fromOrd(int i) {
if (i < 0 || i >= Ints.values().length) {
throw IndexOutOfBoundsException("Invalid ordinal");
}
return Ints.values();
}
}



this means I have to duplicate this code on every Enum. Frustrating!

might work. Alternatively you can build you own ordinal system that
can use values you define, although it's a bit of a PITA:

enum Ints {
ZERO(0),
ONE(1),
TWO(2),
THREE(3),
FOUR(4);

private final int _ord;

Ints(int i) {
_ord = i;
}

int getOrd() { return _ord; }
}


More frustrating!

Diego

Heinz wrote a good article on this. If you haven't read his
newsletters yet, there very good.

http://www.javaspecialists.co.za/archive/Issue113.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top