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

Convert java.nio.ByteOrder to an enum

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • 26
    • core-libs
    • None
    • source, binary, behavioral
    • minimal
    • Hide
      The compatibility risk is minimal, the Enum version of ByteOrder is compatible as the fields and methods. There is a minimal risk of serialization incompatibility of ByteOrder.class object due to the change from class to enum. It is unlikely that serialized ByteOrder class objects exist since ByteOrder is not Serializable.
      Show
      The compatibility risk is minimal, the Enum version of ByteOrder is compatible as the fields and methods. There is a minimal risk of serialization incompatibility of ByteOrder.class object due to the change from class to enum. It is unlikely that serialized ByteOrder class objects exist since ByteOrder is not Serializable.
    • Java API
    • SE

      Summary

      Convert java.nio.ByteOrder to an enum for use in switch.

      Problem

      The java.nio.ByteOrder class predates the addition of enum to the language and has a number of characteristics in common with enums, but is limited, for example: Checking for big or little endian compares the constants against the native byte order as in:

           if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
               // Big endian action
           } else {
               // Little endian action
           }

      ByteOrder can be used in switch when combined with patterns and more boilerplate for a default value:

           var i = switch (ByteOrder.nativeOrder()) {
               case ByteOrder b when b.equals(ByteOrder.LITTLE_ENDIAN) -> 1;
               case ByteOrder b when b.equals(ByteOrder.BIG_ENDIAN)    -> 2;
               default -> throw new IllegalStateException("not supported");
           };

      If ByteOrder were an enum the example would use an expression switch statement:

          var label = switch (Byteorder.nativeOrder()) {
              case LITTLE_ENDIAN -> "Little";
              case BIG_ENDIAN -> "Big";
          }

      The original design of ByteOrder was structured to be similar to enums and has the same function and methods. The class is final and the static constants for the values of BIG_ENDIAN and LITTLE_ENDIAN are the enum values.

      ByteOrderis not Serializable; its instances can not be serialized. All classes can be serialized, including ByteOrder.class.

      The serialized form of ByteOrder.class identifies it as a class, not a Enum. This could be a compatibility risk if ByteOrder.class object has been serialized; but that seems unlikely.

      The reflection view of the class ByteOrder is much the same as the enum ByteOrder. All of the declared fields and methods of the class are present in the enum ByteOrder. The enum ByteOrder has additional fields and methods related to the enum values.

      A corpus search has found only the expected uses as field values, method invocations, parameters, and returns.

      A prototype converting ByteOrder to an enum did not require any source changes to the uses of ByteOrder.

      The change is source, binary, and behaviorally compatible.

      Solution

      Change java.nio.ByteOrder to be an Enum. The minimal changes declare it as public enum ByteOrder and its values as LITTLE_ENDIAN and BIG_ENDIAN.

      Enum instances are Comparable , previously LITTLE_ENDIAN and BIG_ENDIAN could not be compared. As enums, they can be compared and it seems intuitive that LITTLE_ENDIAN is "less than" BIG_ENDIAN . Declaring LITTLE_ENDIAN before BIG_ENDIAN gives them ordinals of 0, 1 respectively and the desired ordering between the values.

      The implementation changes remove a private constructor and a private field.

      The enum ByteOrder is serializable as any other enum, using the name of the value and the enum class name.

      The ByteOrder class object is not serialization compatible, because the flags in the serialized form identify it as a class and in the serialized form of the enum ByteOrder it is identified as an enum. They are incompatible according to serialization specification.
      Generally, class objects, including ByteOrder are rarely serialized unless their instances are serialized and ByteOrder is not Serializable; there are no serialized instances.

      The change is source compatible, binary compatible, and behaviorally compatible.

      Specification

      The javadoc of the class describes ByteOrder as a type-safe enumeration and it is now formally an Enum.

      The descriptions of the BIG_ENDIAN and LITTLE_ENDIAN values remain the same.

      Convenience methods of isBigEndian() and isLittleEndian() are added as predicates for common conditions tested. Frequently those are comparisons to the nativeOrder(), for example:

           if (ByteOrder.nativeOrder().isBigEndian()) {
               // Big endian action
           } else {
               // Little endian action
           }

      The complete specification of java.nio.ByteOrder is:

       /**
       * A typesafe enumeration for byte orders.
       *
       * @author Mark Reinhold
       * @author JSR-51 Expert Group
       * @since 1.4
       */
      
      public enum ByteOrder  {
          /**
           * Constant denoting little-endian byte order.  In this order, the bytes of
           * a multibyte value are ordered from least significant to most
           * significant.
           */
          LITTLE_ENDIAN,
          /**
           * Constant denoting big-endian byte order.  In this order, the bytes of a
           * multibyte value are ordered from most significant to least significant.
           */
          BIG_ENDIAN;
      
          /**
           * Retrieves the native byte order of the underlying platform.
           *
           * <p> This method is defined so that performance-sensitive Java code can
           * allocate direct buffers with the same byte order as the hardware.
           * Native code libraries are often more efficient when such buffers are
           * used.  </p>
           *
           * @return  The native byte order of the hardware upon which this Java
           *          virtual machine is running
           */
          public static ByteOrder nativeOrder() {...}
      
          /**
           * {@return {@code true} if this byte order is BIG_ENDIAN}
           * @since 26
           */
          public boolean isBigEndian() {...}
      
          /**
           * {@return {@code true} if this byte order is LITTLE_ENDIAN}
           * @since 26
           */
          public boolean isLittleEndian() {...}
      
          /**
           * Constructs a string describing this object.
           *
           * <p> This method returns the string
           * {@code "BIG_ENDIAN"} for {@link #BIG_ENDIAN} and
           * {@code "LITTLE_ENDIAN"} for {@link #LITTLE_ENDIAN}.
           *
           * @return  The specified string
           */
          public String toString() {...}
      }

            rriggs Roger Riggs
            rriggs Roger Riggs
            Chen Liang
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: