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.
ByteOrder
is 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() {...}
}
- csr of
-
JDK-8362637 Convert java.nio.ByteOrder to an enum
-
- Open
-