Package org.apache.sis.util

## Class Numbers

- Object
- - Static
  - - Numbers

-     public final class Numbers
      extends Static

  Static methods working with `Number` objects, and a few primitive types by extension.
  Since:
    0.3
  See Also:
    `MathFunctions`

  Defined in the `sis-utility` module

- - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `static byte` | `BIG_DECIMAL` | Constant of value 11 used in `switch` statements or as index in arrays.
    `static byte` | `BIG_INTEGER` | Constant of value 10 used in `switch` statements or as index in arrays.
    `static byte` | `BOOLEAN` | Constant of value 1 used in `switch` statements or as index in arrays.
    `static byte` | `BYTE` | Constant of value 3 used in `switch` statements or as index in arrays.
    `static byte` | `CHARACTER` | Constant of value 2 used in `switch` statements or as index in arrays.
    `static byte` | `DOUBLE` | Constant of value 9 used in `switch` statements or as index in arrays.
    `static byte` | `FLOAT` | Constant of value 8 used in `switch` statements or as index in arrays.
    `static byte` | `FRACTION` | Constant of value 7 used in `switch` statements or as index in arrays.
    `static byte` | `INTEGER` | Constant of value 5 used in `switch` statements or as index in arrays.
    `static byte` | `LONG` | Constant of value 6 used in `switch` statements or as index in arrays.
    `static byte` | `OTHER` | Constant of value 0 used in `switch` statements or as index in arrays.
    `static byte` | `SHORT` | Constant of value 4 used in `switch` statements or as index in arrays.

  - ### Method Summary

    All Methods Static Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `static <N extends Number> N` | `cast​(Number number, Class<N> type)` | Casts a number to the specified type.
    `static byte` | `getEnumConstant​(Class<?> type)` | Returns a numeric constant for the given type.
    `static boolean` | `isFloat​(Class<?> type)` | Returns `true` if the given `type` is a floating point type.
    `static boolean` | `isInteger​(Class<?> type)` | Returns `true` if the given `type` is an integer type.
    `static Class<? extends Number>` | `narrowestClass​(Class<? extends Number> c1, Class<? extends Number> c2)` | Returns the narrowest of the given types.
    `static Class<? extends Number>` | `narrowestClass​(Number value)` | Returns the smallest class capable to hold the specified value.
    `static Class<? extends Number>` | `narrowestClass​(Number n1, Number n2)` | Returns the narrowest type of two numbers.
    `static Number` | `narrowestNumber​(Number value)` | Returns the given number wrapped in the smallest class capable to hold the specified value.
    `static Number` | `narrowestNumber​(String value)` | Returns the smallest number capable to hold the specified value.
    `static int` | `primitiveBitCount​(Class<?> type)` | Returns the number of bits used by primitive of the specified type.
    `static Class<?>` | `primitiveToWrapper​(Class<?> type)` | Changes a primitive class to its wrapper (for example `int` to `Integer`).
    `static <T> T` | `valueOf​(String value, Class<T> type)` | Converts the specified string into a value object.
    `static <T> T` | `valueOfNil​(Class<T> type)` | Returns a `NaN`, zero, empty or `null` value of the given type.
    `static Class<? extends Number>` | `widestClass​(Class<? extends Number> c1, Class<? extends Number> c2)` | Returns the widest of the given types.
    `static Class<? extends Number>` | `widestClass​(Number n1, Number n2)` | Returns the widest type of two numbers.
    `static <N extends Number> N` | `wrap​(double value, Class<N> type)` | Wraps the given floating-point value in a `Number` of the specified class.
    `static <N extends Number> N` | `wrap​(long value, Class<N> type)` | Wraps the given integer value in a `Number` of the specified class.
    `static Class<?>` | `wrapperToPrimitive​(Class<?> type)` | Changes a wrapper class to its primitive (for example `Integer` to `int`).

    - ### Methods inherited from class Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### BIG_DECIMAL

          public static final byte BIG_DECIMAL

      Constant of value 11 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### BIG_INTEGER

          public static final byte BIG_INTEGER

      Constant of value 10 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### FRACTION

          public static final byte FRACTION

      Constant of value 7 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### DOUBLE

          public static final byte DOUBLE

      Constant of value 9 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### FLOAT

          public static final byte FLOAT

      Constant of value 8 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### LONG

          public static final byte LONG

      Constant of value 6 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### INTEGER

          public static final byte INTEGER

      Constant of value 5 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### SHORT

          public static final byte SHORT

      Constant of value 4 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### BYTE

          public static final byte BYTE

      Constant of value 3 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### CHARACTER

          public static final byte CHARACTER

      Constant of value 2 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### BOOLEAN

          public static final byte BOOLEAN

      Constant of value 1 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

    - #### OTHER

          public static final byte OTHER

      Constant of value 0 used in `switch` statements or as index in arrays. This enumeration provides the following guarantees (some Apache SIS codes rely on them):
      - `OTHER` value is 0.
      - Primitive types are enumerated in this exact order (from lower value to higher value, but not necessarily as consecutive values): `BYTE`, `SHORT`, `INTEGER`, `LONG`, `FLOAT`, `DOUBLE`.
      - `java​.math` types of greater capacity than primitive types (`BIG_DECIMAL` and `BIG_INTEGER`) have higher enumeration values.
      - `Fraction` is considered as a kind of floating point value.
      See Also:
        Constant Field Values

  - ### Method Detail

    - #### isFloat

          public static boolean isFloat​(Class<?> type)

      Returns `true` if the given `type` is a floating point type. The floating point types are `Float`, `float`, `Double`, `double` and `BigDecimal`. `Fraction` is also considered as a kind of floating point values.
      Parameters:
        `type` - the primitive type or wrapper class to test (can be `null`).
      Returns:
        `true` if `type` is one of the known types capable to represent floating point numbers.
      See Also:
        `isInteger(Class)`

    - #### isInteger

          public static boolean isInteger​(Class<?> type)

      Returns `true` if the given `type` is an integer type. The integer types are `Byte`, `byte`, `Short`, `short`, `Integer`, `int`, `Long`, `long` and `BigInteger`.
      Parameters:
        `type` - the primitive type or wrapper class to test (can be `null`).
      Returns:
        `true` if `type` is an integer type.
      See Also:
        `isFloat(Class)`

    - #### primitiveBitCount

          public static int primitiveBitCount​(Class<?> type)
                                       throws IllegalArgumentException

      Returns the number of bits used by primitive of the specified type. The given type must be a primitive type or its wrapper class.
      Parameters:
        `type` - the primitive type (can be `null`).
      Returns:
        the number of bits, or 0 if `type` is null.
      Throws:
        `IllegalArgumentException` - if the given type is not one of the types supported by this `Numbers` class.

    - #### primitiveToWrapper

          public static Class<?> primitiveToWrapper​(Class<?> type)

      Changes a primitive class to its wrapper (for example `int` to `Integer`). If the specified class is not a primitive type, then it is returned unchanged.
      Parameters:
        `type` - the primitive type (can be `null`).
      Returns:
        the type as a wrapper.
      See Also:
        `wrapperToPrimitive(Class)`

    - #### wrapperToPrimitive

          public static Class<?> wrapperToPrimitive​(Class<?> type)

      Changes a wrapper class to its primitive (for example `Integer` to `int`). If the specified class is not a wrapper type, then it is returned unchanged.
      Parameters:
        `type` - the wrapper type (can be `null`).
      Returns:
        the type as a primitive.
      See Also:
        `primitiveToWrapper(Class)`

    - #### widestClass

          public static Class<? extends Number> widestClass​(Number n1,
                                                            Number n2)
                                                     throws IllegalArgumentException

      Returns the widest type of two numbers. Numbers `n1` and `n2` can be instance of `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` or `BigDecimal` types.

      If one of the given argument is null, then this method returns the class of the non-null argument. If both arguments are null, then this method returns `null`.

      Parameters:
        `n1` - the first number, or `null`.
        `n2` - the second number, or `null`.
      Returns:
        the widest type of the given numbers, or `null` if both `n1` and `n2` are null.
      Throws:
        `IllegalArgumentException` - if a number is not an instance of a supported type.
      See Also:
        `widestClass(Number, Number)`, `narrowestClass(Number, Number)`

    - #### widestClass

          public static Class<? extends Number> widestClass​(Class<? extends Number> c1,
                                                            Class<? extends Number> c2)
                                                     throws IllegalArgumentException

      Returns the widest of the given types. Classes `c1` and `c2` can be `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` or `BigDecimal` types.

      If one of the given argument is null, then this method returns the non-null argument. If both arguments are null, then this method returns `null`.

      Example: in the following code, `type` is set to `Long​.class`:

      >     Class<?> type = widestClass(Short.class, Long.class);

      Parameters:
        `c1` - the first number type, or `null`.
        `c2` - the second number type, or `null`.
      Returns:
        the widest of the given types, or `null` if both `c1` and `c2` are null.
      Throws:
        `IllegalArgumentException` - if one of the given types is not supported by this `Numbers` class.
      See Also:
        `widestClass(Class, Class)`, `narrowestClass(Number, Number)`

    - #### narrowestClass

          public static Class<? extends Number> narrowestClass​(Number n1,
                                                               Number n2)
                                                        throws IllegalArgumentException

      Returns the narrowest type of two numbers. Numbers `n1` and `n2` can be instance of `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` or `BigDecimal` types.
      Parameters:
        `n1` - the first number, or `null`.
        `n2` - the second number, or `null`.
      Returns:
        the narrowest type of the given numbers, or `null` if both `n1` and `n2` are null.
      Throws:
        `IllegalArgumentException` - if a number is not an instance of a supported type.
      See Also:
        `narrowestClass(Class, Class)`, `widestClass(Class, Class)`

    - #### narrowestClass

          public static Class<? extends Number> narrowestClass​(Class<? extends Number> c1,
                                                               Class<? extends Number> c2)
                                                        throws IllegalArgumentException

      Returns the narrowest of the given types. Classes `c1` and `c2` can be `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` or `BigDecimal` types.

      If one of the given argument is null, then this method returns the non-null argument. If both arguments are null, then this method returns `null`.

      Example: in the following code, `type` is set to `Short​.class`:

      >     Class<?> type = widestClass(Short.class, Long.class);

      Parameters:
        `c1` - the first number type, or `null`.
        `c2` - the second number type, or `null`.
      Returns:
        the narrowest of the given types, or `null` if both `c1` and `c2` are null.
      Throws:
        `IllegalArgumentException` - if one of the given types is not supported by this `Numbers` class.
      See Also:
        `narrowestClass(Number, Number)`, `widestClass(Class, Class)`

    - #### narrowestClass

          public static Class<? extends Number> narrowestClass​(Number value)

      Returns the smallest class capable to hold the specified value. This method applies the following choices, in that order:
      - If the given value is `null`, then this method returns `null`.
      - Otherwise if the given value can not be casted from `double` to another type without precision lost, return `Double​.class`.
      - Otherwise if the given value can not be casted from `float` to another type without precision lost, return `Float​.class`.
      - Otherwise if the given value is between -128 and 127, then this method returns `Byte​.class`;
      - Otherwise if the given value is between -32768 and 32767, then this method returns `Short​.class`;
      - Otherwise if the given value is between -2147483648 and 2147483647, then this method returns `Integer​.class`;
      - Otherwise this method returns `Long​.class`;
      Parameters:
        `value` - the value to be wrapped in a finer (if possible) `Number`.
      Returns:
        the narrowest type capable to hold the given value.
      See Also:
        `narrowestNumber(Number)`

    - #### narrowestNumber

          public static Number narrowestNumber​(Number value)

      Returns the given number wrapped in the smallest class capable to hold the specified value. This method is equivalent to the following code, in a slightly more efficient way:

      >     return cast(value, narrowestClass(value));

      Parameters:
        `value` - the value to be wrapped in a finer (if possible) `Number`.
      Returns:
        the narrowest type capable to hold the given value.
      See Also:
        `narrowestClass(Number)`, `cast(Number, Class)`

    - #### narrowestNumber

          public static Number narrowestNumber​(String value)
                                        throws NumberFormatException

      Returns the smallest number capable to hold the specified value.
      Parameters:
        `value` - the value to be wrapped in a `Number`.
      Returns:
        the narrowest type capable to hold the given value.
      Throws:
        `NumberFormatException` - if the given value can not be parsed as a number.
      See Also:
        `narrowestNumber(Number)`

    - #### cast

          public static <N extends Number> N cast​(Number number,
                                                  Class<N> type)
                                           throws IllegalArgumentException

      Casts a number to the specified type. The target type can be one of `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` or `BigDecimal`. This method makes the following choice:
      - If the given value is `null` or an instance of the given type, then it is returned unchanged.
      - Otherwise if the given type is `Double​.class`, then this method returns `Double​.valueOf(number​.doubleValue())`;
      - Otherwise if the given type is `Float​.class`, then this method returns `Float​.valueOf(number​.floatValue())`;
      - And likewise for all remaining known types.
      This method does not verify if the given type is wide enough for the given value, because the type has typically been calculated by `widestClass(Class, Class)` or `narrowestClass(Number)`. If nevertheless the given type is not wide enough, then the behavior depends on the implementation of the corresponding `Number​.fooValue()` method - typically, the value is just rounded or truncated.
      Type Parameters:
        `N` - the class to cast to.
      Parameters:
        `number` - the number to cast, or `null`.
        `type` - the destination type.
      Returns:
        the number casted to the given type, or `null` if the given value was null.
      Throws:
        `IllegalArgumentException` - if the given type is not supported by this `Numbers` class, or the type is `FRACTION` and the given number can not be converted to that type.

    - #### wrap

          public static <N extends Number> N wrap​(double value,
                                                  Class<N> type)
                                           throws IllegalArgumentException

      Wraps the given floating-point value in a `Number` of the specified class. The given type shall be one of `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` and `BigDecimal` classes. Furthermore, the given value shall be convertible to the given class without precision lost, otherwise an `IllegalArgumentException` will be thrown.
      Type Parameters:
        `N` - the wrapper class.
      Parameters:
        `value` - the value to wrap.
        `type` - the desired wrapper class.
      Returns:
        the value wrapped in an object of the given class.
      Throws:
        `IllegalArgumentException` - if the given type is not supported by this `Numbers` class, or if the given value can not be wrapped in an instance of the given class without precision lost.

    - #### wrap

          public static <N extends Number> N wrap​(long value,
                                                  Class<N> type)
                                           throws IllegalArgumentException

      Wraps the given integer value in a `Number` of the specified class. The given type shall be one of `Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Fraction`, `BigInteger` and `BigDecimal` classes. Furthermore, the given value shall be convertible to the given class without precision lost, otherwise an `IllegalArgumentException` will be thrown.
      Type Parameters:
        `N` - the wrapper class.
      Parameters:
        `value` - the value to wrap.
        `type` - the desired wrapper class.
      Returns:
        the value wrapped in an object of the given class.
      Throws:
        `IllegalArgumentException` - if the given type is not supported by this `Numbers` class, or if the given value can not be wrapped in an instance of the given class without precision lost.
      Since:
        0.8

    - #### valueOf

          public static <T> T valueOf​(String value,
                                      Class<T> type)
                               throws IllegalArgumentException,
                                      NumberFormatException

      Converts the specified string into a value object. The value object can be an instance of `BigDecimal`, `BigInteger`, `Fraction`, `Double`, `Float`, `Long`, `Integer`, `Short`, `Byte`, `Boolean`, `Character` or `String` according the specified type. This method makes the following choice:
      - If the given type is `Double​.class`, then this method returns `Double​.valueOf(value)`;
      - If the given type is `Float​.class`, then this method returns `Float​.valueOf(value)`;
      - And likewise for all remaining known types.
      Type Parameters:
        `T` - the requested type.
      Parameters:
        `value` - the value to parse.
        `type` - the requested type.
      Returns:
        the value object, or `null` if `value` was null.
      Throws:
        `IllegalArgumentException` - if `type` is not a recognized type.
        `NumberFormatException` - if `type` is a subclass of `Number` and the string value is not parsable as a number of the specified type.

    - #### valueOfNil

          public static <T> T valueOfNil​(Class<T> type)

      Returns a `NaN`, zero, empty or `null` value of the given type. This method tries to return the closest value that can be interpreted as "none", which is usually not the same than "zero". More specifically:
      - If the given type is a floating point primitive type (`float` or `double`), then this method returns `Float​.NaN` or `Double​.NaN` depending on the given type.
      - If the given type is an integer primitive type or the character type (`long`, `int`, `short`, `byte` or `char`), then this method returns the zero value of the given type.
      - If the given type is the `boolean` primitive type, then this method returns `Boolean​.FALSE`.
      - If the given type is an array or a collection, then this method returns an empty array or collection. The given type is honored on a best effort basis.
      - For all other cases, including the wrapper classes of primitive types, this method returns `null`.
      Despite being defined in the `Numbers` class, the scope of this method has been extended to array and collection types because those objects can also be seen as mathematical concepts.
      Type Parameters:
        `T` - the compile-time type of the requested object.
      Parameters:
        `type` - the type of the object for which to get a nil value.
      Returns:
        an object of the given type which represents a nil value, or `null`.
      See Also:
        `NilObject`

    - #### getEnumConstant

          public static byte getEnumConstant​(Class<?> type)

      Returns a numeric constant for the given type. The constants are `BIG_DECIMAL`, `BIG_INTEGER`, `FRACTION`, `DOUBLE`, `FLOAT`, `LONG`, `INTEGER`, `SHORT`, `BYTE`, `CHARACTER`, `BOOLEAN`, or `OTHER` constants for the given type. This is a commodity for usage in `switch` statements.
      Parameters:
        `type` - a type (usually either a primitive type or its wrapper), or `null`.
      Returns:
        the constant for the given type, or `OTHER` if unknown.