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.
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 )
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);
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
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.
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"
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).
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.
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();
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
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.
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.
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).
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
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);
The Boolean class defines the following wrapper objects to represent the primitive values true and false, respectively:
Boolean.TRUE Boolean.FALSE