ordinal() returns inconsistent values?

Discussion in 'Java' started by Todd, Apr 8, 2010.

  1. Todd

    Todd Guest

    Hello,

    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?

    BTW, the semantics of the enum will stay the same, an enumerated value
    that was once greater than another will continue to be so. It is just
    that the absolute value of the declared enumeration will not
    necessarily be the same from run to run. This indicates to me that
    one would not be able to retrieve an enumerated element by a stored
    ordinal value. Further, the ordinal could be a value greater than the
    number of enumerated elements, making values()[ordinal()] suspect as
    well.

    Any insights are appreciated,
    Todd
    Todd, Apr 8, 2010
    #1
    1. Advertising

  2. Todd

    Mayeul Guest

    Hello,

    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?


    Never observed this, and it would be contradictory with the JavaDoc of
    Enum.ordinal() . I often expect ordinal() to behave as specified, and
    have never noticed this expectation to break anything.

    > [...] This indicates to me that
    > one would not be able to retrieve an enumerated element by a stored
    > ordinal value.


    Well that /is/ pretty unsafe to do anyway. What if you need to
    add/remove/swap enum values?
    I usually store their name instead, or try to think up some safe enough
    serialization.

    > [...]


    --
    Mayeul
    Mayeul, Apr 8, 2010
    #2
    1. Advertising

  3. 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

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Apr 8, 2010
    #3
  4. Todd

    Todd Guest

    On Apr 8, 11:43 am, Joshua Cranmer <> 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
    >
    > --
    > Beware of bugs in the above code; I have only proved it correct, not
    > tried it. -- Donald E. Knuth


    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.
    Todd, Apr 8, 2010
    #4
  5. In article
    <>,
    Todd <> wrote:

    > On Apr 8, 11:43 am, Joshua Cranmer <> 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.


    I'd have thought to avoid ordinal(), as suggested by Joshua Bloch,
    "Item 31: Use instance fields instead of ordinals."

    Regarding serialization, section 1.12 of "Java Object Serialization
    Specification," entitled "Serialization of Enum Constants," mentions
    using "the value returned by the enum constant's name method."

    <http://java.sun.com/javase/6/docs/platform/serialization/spec/serialTOC.html>

    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
    John B. Matthews, Apr 8, 2010
    #5
  6. Todd

    Lew Guest

    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?

    >


    Joshua Cranmer wrote:
    >> 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

    >


    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.
    >


    "I was told ..."

    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?

    --
    Lew
    Please do not quote sigs.
    Lew, Apr 8, 2010
    #6
  7. John B. Matthews wrote:

    >
    > Regarding serialization, section 1.12 of "Java Object Serialization
    > Specification," entitled "Serialization of Enum Constants," mentions
    > using "the value returned by the enum constant's name method."
    >
    > <http://java.sun.com/javase/6/docs/platform/serialization/spec/serialTOC.html>


    Of course. You wouldn't want stuff to break [1] because the enum values had
    been reordered between serialization and deserialization.

    1. E.g. to silently turn SPRING into AUTUMN because the order was changed
    from chronological to alphabetical.
    Mike Schilling, Apr 8, 2010
    #7
  8. Lew wrote:
    > 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?

    >>

    >
    > Joshua Cranmer wrote:
    >>> 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

    >>

    >
    > 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.
    >>

    >
    > "I was told ..."
    >
    > 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?


    To the last point, not necessarily, so long as it's consistent within a JVM
    session and those classes are persisted in a way that doesn't assume it's
    consistent across JVMs. Likewise, I think (though I could be wrong) that

    1. Create a TreeMap
    2. Serialize it to a file
    3. Make code changes that change the ordering defined on its keys
    4. Deserialize it

    works.
    Mike Schilling, Apr 8, 2010
    #8
  9. Todd

    Daniel Pitts Guest

    On 4/8/2010 9:13 AM, Todd wrote:
    > Hello,
    >
    > 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?
    >
    > BTW, the semantics of the enum will stay the same, an enumerated value
    > that was once greater than another will continue to be so. It is just
    > that the absolute value of the declared enumeration will not
    > necessarily be the same from run to run. This indicates to me that
    > one would not be able to retrieve an enumerated element by a stored
    > ordinal value. Further, the ordinal could be a value greater than the
    > number of enumerated elements, making values()[ordinal()] suspect as
    > well.
    >
    > Any insights are appreciated,
    > Todd

    That is incorrect. If the order remains the same (and it must), and the
    ordinal() result corresponds with the index into the values() array (and
    it must), and the values() array can not contain null (and it mustn't),
    then the ordinal() value must be the same, for the same enum class,
    every invocation.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Apr 8, 2010
    #9
  10. Todd

    Todd Guest

    On Apr 8, 1:58 pm, Lew <> 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.
    Todd, Apr 8, 2010
    #10
  11. 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
    Joshua Cranmer, Apr 8, 2010
    #11
  12. Todd

    Arne Vajhøj Guest

    On 08-04-2010 14:27, Todd wrote:
    > On Apr 8, 11:43 am, Joshua Cranmer<> 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
    Arne Vajhøj, Apr 9, 2010
    #12
  13. Todd

    Arne Vajhøj Guest

    On 08-04-2010 16:51, Todd wrote:
    > On Apr 8, 1:58 pm, Lew<> 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
    Arne Vajhøj, Apr 9, 2010
    #13
  14. Todd

    Roedy Green Guest

    On Thu, 8 Apr 2010 09:13:05 -0700 (PDT), Todd
    <> wrote, quoted or indirectly quoted someone
    who said :

    >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?


    If you add new enum constants, or run a code tidier, you will get
    different ordinal values.

    Assuming you did not change the code, perhaps you failed to clean
    recompile the universe after the last change and a mix of old and new
    code was used that caused the anomaly.

    Can you make this happen on command in an SSCCE?

    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.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    Pfizer’s world wide patents on Viagra will expire over the period 2010 to 2013. This will launch an avalanche of cheap generics. Wrigley has even patented a chewing gum containing generic Viagra.
    Roedy Green, Apr 9, 2010
    #14
  15. Todd

    Lew Guest

    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
    Lew, Apr 9, 2010
    #15
  16. Todd

    Roedy Green Guest

    On Thu, 08 Apr 2010 16:57:48 -0400, Joshua Cranmer
    <> wrote, quoted or indirectly quoted someone
    who said :

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


    I have posted decompilations of several enum-using programs at
    http://mindprod.com/jgloss/enum.html

    I see no sign of how ordinals could change without changing source and
    recompiling. I have not studied the serialization code. I use it all
    the time, and have never noticed anything untoward.

    As usual, your program is likely confidential, long and complex, and
    when you try to write an SSCCE the problem goes way. The IntelliJ
    people have assured me, in that case, they are happy to get a huge
    SSCCE, so long it is complete enough for them to run it.

    Is your code posted anywhere?

    For now, I would suggest a clean compile, and see if the assignments
    magically become stable.

    By any chance are you storing ordinals in a database or flat files?
    These will go out of date the instant you add another enum or tidy the
    source code enum order.

    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    Pfizer’s world wide patents on Viagra will expire over the period 2010 to 2013. This will launch an avalanche of cheap generics. Wrigley has even patented a chewing gum containing generic Viagra.
    Roedy Green, Apr 10, 2010
    #16
  17. Todd

    Todd Guest

    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
    Todd, Apr 12, 2010
    #17
  18. Todd

    Lew Guest

    Todd wrote:
    > 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.


    Some of the real dangers of ordinals have been explained in this thread,
    including by Roedy in the message to which you responded here.

    --
    Lew
    Lew, Apr 12, 2010
    #18
  19. Todd

    Arne Vajhøj Guest

    On 12-04-2010 15:43, Todd wrote:
    > 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.


    So you heard from someone that heard from someone that got
    the info from an unidentified source.

    :)

    BTW, ordinal returning inconsistent values and ordinals
    being of little value for programmers are two very different things.

    Arne
    Arne Vajhøj, Apr 14, 2010
    #19
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. SamIAm
    Replies:
    1
    Views:
    1,513
    Andrew de la Harpe
    Sep 29, 2003
  2. Replies:
    4
    Views:
    2,179
  3. Ion Chalmers Freeman

    Re: Ordinal Expression from String

    Ion Chalmers Freeman, Jul 27, 2003, in forum: Java
    Replies:
    0
    Views:
    696
    Ion Chalmers Freeman
    Jul 27, 2003
  4. Chris Smith
    Replies:
    1
    Views:
    799
    Adam Maass
    May 16, 2005
  5. fishfry

    Inconsistent returns from piped open

    fishfry, Feb 17, 2006, in forum: Perl Misc
    Replies:
    4
    Views:
    98
    Csaba
    Feb 18, 2006
Loading...

Share This Page