Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4071284

Class variable initialization depends on placement of statements in file

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 1.1.3
    • tools
    • None
    • x86
    • windows_nt



      Name: tb29552 Date: 08/12/97


      Dear People,

         I'm not 100% sure that the behavior I'm going to describe
      is not intentional, but just in case, here are the details.
      I have created a class that represents an enumerated type Color
      The class defines a number of public static final Color objects
      that represent various Colors. On top of that, there are two class
      variables: head and tail, that reference the first and the last
      defined constant. Creating a new Color object changes the values
      of head and tail. How the change is seen outside depends on the order
      of lines in the source code. This strikes me as a bit odd and hence
      this message.

      Here is the full code of the Color class

      public final class Color {

         // moving this one changes nothing
         private static int count = 0; // counter for Colors
         // THESE LINES MAY CAUSE DIFFEREN BEHAVIOR
         private static Color head = null; // the first constant
         private static Color tail = null; // the last constant

         //////////////////////////////////////////////
         // public constants of the enumerated type //
         //////////////////////////////////////////////
         public static final Color RED = new Color( "Red" );
         public static final Color BLUE = new Color( "Blue" );
         public static final Color BLACK = new Color( "Black" );
         public static final Color PINK = new Color( "Pink" );
         // .. etc. and so on
         public static final Color GREEN = new Color( "Green" );

         /**
          * maps the enumerated constant to an integer. Can be used to
          * access arrays, as in Color x = Color.BLUE; ... c[x.ord] = 1;
          **/
         public final int ord;

         /**
          * Returns a textual representation of the enumerated constant.
          **/
         public String toString() { return this.name; }

         /**
          * returns the constant that follows this one.
          **/
         public Color pred() { return this.prev; }

         /**
          * returns the constant that preceds this one.
          **/
         public Color succ() { return this.next; }

         /**
          * returns the number of constants defined for this enumeration.
          **/
         public static int size() { return count; }

         /**
          * return the first constant in the enumeration.
          **/
         public static Color first() { return head; }

         /**
          * returns the last constant in the enumeration.
          **/
         public static Color last() { return tail; }

         /////////////////////////////////////////////////
         // private parts
         /////////////////////////////////////////////////

         private Color( String id ) {
            name = id;
            ord = count++;
            if( head == null )
               head = this;
            if( tail != null ) {
               this.prev = tail;
               tail.next = this;
            }
            tail = this;
         }/* Color */

         private String name; // name of the constant
         private Color prev; // preceding Color
         private Color next; // the color that follows

      }/* class Color */

      In the code above a number (2) of lines is marked as
      THESE LINES MAY CAUSE DIFFERET BEHAVIOR. If you move
      them below lines that introduce RED, BLUE, etc. the
      functionality of the class is broken. What happens is
      that if Color constant are declared first followed by
      private static constants, the Color constants will be
      created, modifying private constants, but then the last
      4 or so instruction of the static{} block will reset
      head and tail to null. Surprisingly, they do not reset
      count, which remains at 5. Thus moving count around
      has no impact on the program behavior, but moving
      declarations of head and tail does. This, like I said,
      can be perceived as anomally. The reason I have came
      across the above is because I tend to place private
      members at the bottom of the class and public at the top.
      Clearly, in this case, it leads to undesired effects.
      While it is difficult to avoid interdependecies between
      static variables, I would think that they would affect
      ALL static varibles, count included. However, this is not
      the case.
      company - University of Newcastle , email - ###@###.###
      ======================================================================

            tturnidgsunw Todd Turnidge (Inactive)
            tbell Tim Bell
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: