From: Joshua Cranmer on
On 04/08/2010 02:27 PM, Todd wrote:
> I fully agree. I was told that the JavaDocs were wrong. I tried
> locating a source on the web to corroborate the assertion, but
> couldn't find one.

If you've ever looked at how enums are created (via javap -c), you'll
notice that you'll get something akin to [1]:

public final class Seasons extends Enum<Seasons> {
public final static Seasons SPRING = new Seasons("SPRING", 0);
public final static Seasons SUMMER = new Seasons("SUMMER", 1);
public final static Seasons AUTUMN = new Seasons("AUTUMN", 2);
public final static Seasons WINTER = new Seasons("WINTER", 3);

private Seasons(String name, int ordinal) {
super(name, ordinal);
}
}

In other words, the ordinal is hardcoded into the class file at compile
time. Reading the JavaDocs should also give you this opinion, since the
only constructor it has is protected Enum(String name, int ordinal).

[1] I'm eliding the $VALUES variable and initialization, as well as the
values and valueOf functions. Also, what a coincidence that the four
seasons have the same lengths in their words in English.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
From: Arne Vajhøj on
On 08-04-2010 14:27, Todd wrote:
> On Apr 8, 11:43 am, Joshua Cranmer<Pidgeo...(a)verizon.invalid> wrote:
>> On 04/08/2010 12:13 PM, Todd wrote:
>>> I have recently been told that the ordinal() method in a Java enum
>>> will not necessarily return the same value in different invocations of
>>> the JVM. Has anyone else found this?
>>
>> To do so would contradict the API:
>> public final int ordinal()
>>
>> Returns the ordinal of this enumeration constant (its position in
>> its enum declaration, where the initial constant is assigned an ordinal
>> of zero). Most programmers will have no use for this method. It is
>> designed for use by sophisticated enum-based data structures, such as
>> EnumSet and EnumMap.
>>
>> Returns:
>> the ordinal of this enumeration constant
>
> I fully agree. I was told that the JavaDocs were wrong. I tried
> locating a source on the web to corroborate the assertion, but
> couldn't find one.

Unless there are evidence supporting the claim, then I would
expect the docs to be correct and the "smart guy" to be
wrong.

Arne


From: Arne Vajhøj on
On 08-04-2010 16:51, Todd wrote:
> On Apr 8, 1:58 pm, Lew<l...(a)lewscanon.com> wrote:
>> Who told you? How authoritative is this source usually? What
>> evidence did they give for this outrageous assertion? Wouldn't it
>> break 'EnumSet' and 'EnumMap' if your source were correct?
>
> A fellow here at work who has one of the Sun certifications. He made
> the statement yesterday, but is not in today for me to get more
> clarification.

Being Java certified is no guarantee to be correct on all
Java matters.

Arne
From: Lew on
Roedy Green wrote:
> It is dangerous to write Java code that depends on the ordinal
> remaining invariant. Invent some invariant field on each enum
> constant which might just be a single letter or a short word for use
> in databases to represent the value.

Amen to that!

More generally one nearly always faces the task of mapping an enum to some
untyped representation and back. Of course, enums build that facility in
already with 'name()' and 'valueOf()'.

<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9>
"... the automatically generated methods (values() and valueOf(String)) or
methods that override the final methods in Enum: (equals(Object), hashCode(),
clone(), compareTo(Object), name(), ordinal(), and getDeclaringClass())."

<http://java.sun.com/javase/6/docs/api/java/lang/Enum.html#name()>
"Most programmers should use the toString() method in preference to this one,
as the toString method may return a more user-friendly name." (Original is in
boldface.)

Huh? The very API Javadocs tell you strongly not to use 'name()', which
corresponds to the static 'valueOf(String)'. But what's the static method
that balances 'toString()'? I call mine 'fromString()'.

There's a Hibernate enum converter that takes as parameters the names of the
to- and fro- methods, defaulting to 'name()' and 'valueOf()'.

One's 'fromString()' can be as forgiving or strict as one cares to make it. I
like mine to be case sensitive and to fall back to 'valueOf()' if nothing
better fits. 'fromString( "foo" )' and 'fromString( "FOO" )' would both
return the 'FOO' enum constant in my example below.

template:

/** ${name}.
*/
public enum ${name}
{
// CONSTANTS GO HERE, e.g.,
// FOO( "foo" ),
;

private final String repr;

/**
* Constructor.
* @param rep String representation of enum value.
*/
${name}( String rep )
{
this.repr = rep;
}

@Override
public final String toString()
{
return this.repr;
}

/**
* Look up enum constant from String representation.
* @param rep String representation of enum value.
* @return ${name} constant matching the representation.
*/
public static ${name} fromString( final String rep )
{
if ( rep == null )
{
return null;
}
for ( ${name} val : values() )
{
if ( rep.equals( val.toString() ) )
{
return val;
}
}
return valueOf( rep );
}
}

--
Lew
From: Todd on
Everyone,

Thanks for all of the responses. I have had a chance to speak with
the originator of the issue and he said a guru at a prior workplace
told he and his colleagues to be wary of ordinal. My colleague
believes this statement was made due to the docs indicating that
ordinal is likely to be of little use to developers and is primarily
for internal use. He has yet to get a response from the guru for
confirmation or other sources.

BTW, my colleague cited Roedy's page on enums, not to defend his
position, but just as a reference.

Thanks for all the good info and if/when I get a source for the
warning against ordinal, I will post it.

Todd