10.3 The Wrapper Classes

Wrapper classes were introduced with the discussion of the primitive data types (see Section 2.2, p. 28). Primitive values in Java are not objects. In order to manipulate these values as objects, the java.lang package provides a wrapper class for each of the primitive data types. All wrapper classes are final. The objects of all wrapper classes that can be instantiated are immutable, that is, their state cannot be changed.

Although the Void class is considered a wrapper class, it does not wrap any primitive value and is not instantiable (i.e., has no public constructors). It just denotes the Class object representing the keyword void. The Void class will not be discussed further in this section.

In addition to the methods defined for constructing and manipulating objects of primitive values, the wrapper classes also define useful constants, fields, and conversion methods.

Common Wrapper Class Constructors

The Character class has only one public constructor, taking a char value as parameter. The other wrapper classes all have two public one-argument constructors: one takes a primitive value and the other takes a string.

WrapperType( type v )
WrapperType( String str )


Converting Primitive Values to Wrapper Objects

A constructor that takes a primitive value can be used to create wrapper objects. See (1) in Figure 10.2.

Character charObj1   = new Character('\n');
Boolean   boolObj1   = new Boolean(true);
Integer   intObj1    = new Integer(2003);
Double    doubleObj1 = new Double(3.14);
Figure 10.2. Converting Values between Primitive, Wrapper, and String Types

graphics/10fig02.gif

Converting Strings to Wrapper Objects

A constructor that takes a String object representing the primitive value, can also be used to create wrapper objects. The constructors for the numeric wrapper types throw an unchecked NumberFormatException if the String parameter does not parse to a valid number. See (2a) in Figure 10.2.

Boolean boolObj2   = new Boolean("TrUe");       // case ignored: true
Boolean boolObj3   = new Boolean("XX");         // false
Integer intObj2    = new Integer("2003");
Double  doubleObj2 = new Double("3.14");
Long    longObj1   = new Long("3.14");          // NumberFormatException

Common Wrapper Class Utility Methods

Converting Strings to Wrapper Objects

Each wrapper class (except Character) defines the static method valueOf(String s) that returns the wrapper object corresponding to the primitive value represented by the String object passed as argument (see (6a) in Figure 10.2). This method for the numeric wrapper types also throws a NumberFormatException if the String parameter is not a valid number.

static WrapperType valueOf( String s )


Boolean boolObj4   = Boolean.valueOf("false");
Integer intObj3    = Integer.valueOf("1949");
Double  doubleObj3 = Double.valueOf("-3.0");

In addition to the one-argument valueOf() method, the integer wrapper types define an overloaded static valueOf() method that can take a second argument. This argument specifies the base (or radix) in which to interpret the string representing the signed integer in the first argument:

static WrapperType valueOf( String s, int base )


Byte    byteObj1  = Byte.valueOf("1010", 2);   // Decimal value 10
Short   shortObj2 = Short.valueOf("012", 8);   // Not "\012". Decimal value 10.
Integer intObj4   = Integer.valueOf("-a", 16); // Not "-0xa". Decimal value -10.
Long    longObj2  = Long.valueOf("-a", 16);    // Not "-0xa". Decimal value -10L.
Converting Wrapper Objects to Strings

Each wrapper class overrides the toString() method from the Object class. The overriding method returns a String object containing the string representation of the primitive value in the wrapper object (see (3) in Figure 10.2).

String toString()


String charStr   = charObj1.toString();     // "\n"
String boolStr   = boolObj2.toString();     // "true"
String intStr    = intObj1.toString();      // "2003"
String doubleStr = doubleObj1.toString();   // "3.14"
Converting Primitive Values to Strings

Each wrapper class defines a static method toString(type v) that returns the string corresponding to the primitive value of type passed as argument (see (6a) in Figure 10.2).

static String toString( type v )


String charStr2   = Character.toString('\n');  // "\n"
String boolStr2   = Boolean.toString(true);    // "true"
String intStr2    = Integer.toString(2003);    // Base 10. "2003"
String doubleStr2 = Double.toString(3.14);     // "3.14"

For integer primitive types, the base is assumed to be 10. For floating-point numbers, the textual representation (decimal form or scientific notation) depends on the sign and the magnitude (absolute value) of the number. The NaN value, positive infinity and negative infinity will result in the strings "NaN", "Infinity", and "-Infinity", respectively.

In addition, the wrapper classes Integer and Long define overloaded toString() methods for converting integers to string representation in decimal, binary, octal, and hexadecimal notation (see p. 398).

Converting Wrapper Objects to Primitive Values

Each wrapper class defines a typeValue() method which returns the primitive value in the wrapper object (see (4) in Figure 10.2).

type typeValue()


char    c = charObj1.charValue();           // '\n'
boolean b = boolObj2.booleanValue();        // true
int     i = intObj1.intValue();             // 2003
double  d = doubleObj1.doubleValue();       // 3.14

In addition, each numeric wrapper class defines typeValue() methods for converting the primitive value in the wrapper object to a value of any numeric primitive data type. These methods are discussed below.

Wrapper Comparison, Equality, and Hashcode

Each wrapper class (except Boolean) defines the following method:

int compareTo(WrapperType obj2)


that returns a value which is less than, equal to, or greater than zero, depending on whether the primitive value in the current WrapperType object is less than, equal to, or greater than the primitive value in the WrapperType object denoted by argument obj2.

Each wrapper class (except Boolean) also implements the Comparable interface (see Section 11.6, p. 453), which defines the following method:

int compareTo(Object obj2)


This method is equivalent to the compareTo(WrapperType) method when the current object and the object denoted by the argument obj2 have the same WrapperType. Otherwise, a ClassCastException is thrown.

// Comparisons based on objects created above
Character charObj2   = new Character('a');
int result1 = charObj1.compareTo(charObj2);      //  < 0
int result2 = intObj1.compareTo(intObj3);        //  > 0
int result3 = doubleObj1.compareTo(doubleObj2);  // == 0
int result4 = doubleObj1.compareTo(intObj1);     // ClassCastException

Each wrapper class overrides the equals() method from the Object class. The overriding method compares two wrapper objects for object value equality.

boolean equals(Object obj2)


// Comparisons based on objects created above
boolean charTest   = charObj1.equals(charObj2);      // false
boolean boolTest   = boolObj2.equals(Boolean.FALSE); // false
boolean intTest    = intObj1.equals(intObj2);        // true
boolean doubleTest = doubleObj1.equals(doubleObj2);  // true

Each wrapper class overrides the hashCode() method in the Object class. The overriding method returns a hash value based on the primitive value in the wrapper object.

int hashCode()


int index = charObj1.hashCode();

Numeric Wrapper Classes

The numeric wrapper classes Byte, Short, Integer, Long, Float, and Double are all subclasses of the abstract class Number (see Figure 10.1).

Each numeric wrapper class defines an assortment of constants, including the minimum and maximum value of the corresponding primitive data type:


<wrapper class name>.MIN_VALUE
<wrapper class name>.MAX_VALUE


The following code retrieves the minimum and maximum values of various numeric types:

byte   minByte   = Byte.MIN_VALUE;     // -128
int    maxInt    = Integer.MAX_VALUE;  // 2147483647
double maxDouble = Double.MAX_VALUE;   // 1.7976931348623157e+308
Converting any Numeric Wrapper Object to any Numeric Primitive Type

Each numeric wrapper class defines the following set of typeValue() methods for converting the primitive value in the wrapper object to a value of any numeric primitive type:

byte   byteValue()
short  shortValue()
int    intValue()
long   longValue()
float  floatValue()
double doubleValue()

See also (4) in Figure 10.2.


The following code shows converting of values in numeric wrapper objects to any numeric primitive type.

Byte    byteObj2   = new Byte((byte) 16);       // Cast mandatory
Integer intObj5    = new Integer(42030);
Double  doubleObj4 = new Double(Math.PI);

short  shortVal  = intObj5.shortValue();        // (1)
long   longVal   = byteObj2.longValue();
int    intVal    = doubleObj4.intValue();       // (2) Truncation
double doubleVal = intObj5.doubleValue();

Notice the potential for loss of information at (1) and (2) above, when the primitive value in a wrapper object is converted to a narrower primitive data type.

Converting Strings to Numeric Values

Each numeric wrapper class defines a static method parseType(String s), which returns the primitive numeric value represented by the String object passed as argument. The Type in the method name parseType stands for the name of a numeric wrapper class, except for the name of the Integer class which is abbreviated to Int. These methods throw a NumberFormatException if the String parameter is not a valid argument (see (5) in Figure 10.2.)

type parseType(String s)


byte   value1 = Byte.parseByte("16");
int    value2 = Integer.parseInt("2010");       // parseInt, not parseInteger.
int    value3 = Integer.parseInt("7UP");        // NumberFormatException
double value4 = Double.parseDouble("3.14");

For the integer wrapper types, the overloaded static method parseType() can, in addition, take a second argument, which can specify the base in which to interpret the string representing the signed integer in the first argument:

type parseType(String s, int base)


byte  value6 = Byte.parseByte("1010", 2);    // Decimal value 10
short value7 = Short.parseShort("012", 8);   // Not "\012". Decimal value 10.
int   value8 = Integer.parseInt("-a", 16);   // Not "-0xa". Decimal value -10.
long  value9 = Long.parseLong("-a", 16);     // Not "-0xa". Decimal value -10L.
Converting Integer Values to Strings in different Notations

The wrapper classes Integer and Long provide static methods for converting integers to string representation in decimal, binary, octal, and hexadecimal notation. Some of these methods from the Integer class are listed here, but analogous methods are also defined in the Long class. Example 10.2 demonstrates use of these methods.

static String toBinaryString(int i)
static String toHexString(int i)
static String toOctalString(int i)

These three methods return a string representation of the integer argument as an unsigned integer in base 2, 16, and 8, respectively, with no extra leading zeroes.

static String toString(int i, int base)
static String toString(int i)

The first method returns the minus sign '-' as the first character if the integer i is negative. In all cases, it returns the string representation of the magnitude of the integer i in the specified base.

The last method is equivalent to the method toString(int i, int base), where the base has the value 10, that is, returns the string representation as a signed decimal. (see also (6a) in Figure 10.2).


Example 10.2 String Representation of Integers
public class IntegerRepresentation {
    public static void main(String[] args) {
        int positiveInt = +41;    // 051, 0x29
        int negativeInt = -41;    // 037777777727, -051, 0xffffffd7, -0x29
        System.out.println("String representation for decimal value: "
                           + positiveInt);
        integerStringRepresentation(positiveInt);
        System.out.println("String representation for decimal value: "
                           + negativeInt);
        integerStringRepresentation(negativeInt);
    }

    public static void integerStringRepresentation(int i) {
        System.out.println("    Binary:\t\t" + Integer.toBinaryString(i));
        System.out.println("    Hex:\t\t"    + Integer.toHexString(i));
        System.out.println("    Octal:\t\t"  + Integer.toOctalString(i));
        System.out.println("    Decimal:\t"  + Integer.toString(i));

        System.out.println("    Using toString(int i, int base) method:");
        System.out.println("    Base 2:\t\t" + Integer.toString(i, 2));
        System.out.println("    Base 16:\t"  + Integer.toString(i, 16));
        System.out.println("    Base 8:\t\t" + Integer.toString(i, 8));
        System.out.println("    Base 10:\t"  + Integer.toString(i, 10));
    }
}

Output from the program:

String representation for decimal value: 41
    Binary:     101001
    Hex:        29
    Octal:      51
    Decimal:    41
    Using toString(int i, int base) method:
    Base 2:     101001
    Base 16:    29
    Base 8:     51
    Base 10:    41
String representation for decimal value: -41
    Binary:     11111111111111111111111111010111
    Hex:        ffffffd7
    Octal:      37777777727
    Decimal:    -41
    Using toString(int i, int base) method:
    Base 2:     -101001
    Base 16:    -29
    Base 8:     -51
    Base 10:    -41

Character Class

The Character class defines a myriad of constants, including the following which represent the minimum and the maximum value of the char type (see Section 2.2, p. 29):

Character.MIN_VALUE
Character.MAX_VALUE


The Character class also defines a plethora of static methods for handling various attributes of a character, and case issues relating to characters, as defined by Unicode:

static int     getNumericValue(char ch)
static boolean isLowerCase(char ch)
static boolean isUpperCase(char ch)
static boolean isTitleCase(char ch)
static boolean isDigit(char ch)
static boolean isLetter(char ch)
static boolean isLetterOrDigit(char ch)
static char    toUpperCase(char ch)
static char    toLowerCase(char ch)
static char    toTitleCase(char ch)


The following code converts a lowercase character to an uppercase character:

char ch = 'a';
if (Character.isLowerCase(ch)) ch = Character.toUpperCase(ch);

Boolean Class

The Boolean class defines the following wrapper objects to represent the primitive values true and false, respectively:

Boolean.TRUE
Boolean.FALSE