In Java programming, the java.lang
package plays a pivotal role, containing fundamental classes and interfaces that are automatically imported into every Java program. Among these classes, the wrapper classes stand out as essential components that bridge the gap between primitive data types and objects. In this article, we delve into the nuances of wrapper classes, exploring their significance, usage, and practical applications within the Java ecosystem.
What are Wrapper Classes?
In Java, data types can be classified into two categories: primitive types (such as int, double, boolean) and reference types (objects). While primitive types offer efficiency and simplicity, they lack the ability to participate in object-oriented paradigms directly. Wrapper classes address this limitation by providing an object representation for each primitive type, allowing them to be treated as objects.
Imagine a scenario where you need to store primitive data types (like int
, char
, boolean
) within collections, pass them as arguments to methods expecting objects, or perform operations that leverage object-oriented features. This is where wrapper classes come to the rescue! They essentially “wrap” primitive data types into objects, bestowing upon them the power of object-oriented capabilities.
Wrapper classes’ main objective is to wrap primitives into object form so that we can handle primitives just like objects.
Several utility methods are required for primitives.
Almost all wrapper classes contain two constructors: one that can take corresponding primitives as arguments and another one that can take a string as an argument.
Example 1
Integer I = new Integer(10);
Integer I = new Integer("10");
Example 2
Double D = new Double(10.5);
Double D = new Double("10.5");
Note: If the string argument does not represent a number, then we will get a NumberFormatException
. For example, Integer I = new Integer("ten");
will result in a NumberFormatException
.
Integer I = new Integer("ten"); // Resulting in a NumberFormatException
List of Wrapper Classes
Wrapper classes serve the purpose of encapsulating primitive data types into object form, facilitating the handling of primitives as objects. Each wrapper class provides constructors tailored to accept either the corresponding primitive type or a string representation.
Byte
Constructor Arguments: byte or String
Short
Constructor Arguments: short or String
Integer
Constructor Arguments: int or String
Long
Constructor Arguments: long or String
Float
Constructor Arguments: float, double, or String
Example Usage:
Float f = new Float(10.5f);
Float f = new Float("10.5");
Float f = new Float(10.5);
Float f = new Float("10.5");
Note: Float class can contain three constructors with float, double, and string arguments.
Double
Constructor Arguments: double or String
Character
Constructor Arguments: char
Character ch = new Character('a'); // Correct
Character ch = new Character("a"); // Incorrect
Note: Character class contains only one constructor which can take only one argument, that is, char and does not take a String constructor.
Boolean
Constructor Arguments: boolean or String
Boolean class contains two constructors which can take boolean and String arguments, that is, boolean and String constructor. but there are some twists, Let’s see it.
Case 1: When passing boolean primitives, only allowed values are true and false where case is important and content also very important.
Boolean B = new Boolean(true); // Correct
Boolean B = new Boolean(false); // Correct
Boolean B = new Boolean(True); // Incorrect
Boolean B = new Boolean(amol); // Incorrect
Case 2: When passing a String as an argument, case and content both are not important. If the content is a case-insensitive String of “true”, then it is treated as true; otherwise, it is treated as false.
Boolean B = new Boolean("true"); // true
Boolean B = new Boolean("True"); // true
Boolean B = new Boolean("TRUE"); // true
Boolean B = new Boolean("malaika"); // false
Boolean B = new Boolean("mallika"); // false
Boolean B = new Boolean("jareena"); // false
Let’s see one more example,
Boolean X = new Boolean("yes");
Boolean Y = new Boolean("no");
System.out.println(X); // Output: false
System.out.println(Y); // Output: false
System.out.println(X.equals(Y)); // Output: true
Note: In all wrapper classes, toString
method is overridden to return content directly, and .equals
method is overridden for content comparison.
Utility Methods
1.valueOf()
2.xxxValue()
3.parseXxx()
4.toString()
Here’s the breakdown of the utility methods for wrapper classes:
1. valueOf()
Every wrapper class except the Character class contains a public static method valueOf(String s)
which can take a String as an argument to create the corresponding wrapper class.
public static wrapper valueOf(String s)
Example:
Integer I = Integer.valueOf("10");
Double D = Double.valueOf("10.5");
Boolean B = Boolean.valueOf("softAai");
Form 2
Every integral type wrapper class (Byte, Short, Integer, Long) contains the following valueOf
method to create a wrapper object for the specified radix string.
public static wrapper valueOf(String s, int radix);
Note: Radix is the parameter that specifies the number system to be used. For example, binary = 2, octal = 8, hexadecimal = 16, etc. The allowed range of radix is 2 to 36.
Example:
Integer I = Integer.valueOf("100", 2);
System.out.println(I); // Output: 4
Integer I = Integer.valueOf("101", 4);
System.out.println(I); // Output: 17
Form 3
Every wrapper class including the Character class contains a public static method valueOf(primitive p)
to create a wrapper object for the given primitive.
public static wrapper valueOf(primitive p);
Integer I = Integer.valueOf(10);
Double D = Double.valueOf(10.5);
Character ch = Character.valueOf('a');
In short, valueOf()
methods are used to create wrapper objects for given primitive or string values.
Primitive/String ——– valueOf()
———> Wrapper Object
2. xxxValue()
We can use xxxValue()
methods to get the primitive value from a given wrapper object.
Every number type wrapper class (Integer, Byte, Short, Long, Float, Double) contains the following methods to get primitive values for a given wrapper object:
- byteValue():
- Returns the byte primitive value of the wrapper object.
- Method Signature:
public byte byteValue()
- shortValue():
- Returns the short primitive value of the wrapper object.
- Method Signature:
public short shortValue()
- intValue():
- Returns the int primitive value of the wrapper object.
- Method Signature:
public int intValue()
- longValue():
- Returns the long primitive value of the wrapper object.
- Method Signature:
public long longValue()
- floatValue():
- Returns the float primitive value of the wrapper object.
- Method Signature:
public float floatValue()
- doubleValue():
- Returns the double primitive value of the wrapper object.
- Method Signature: public double doubleValue()
Integer I = new Integer(130);
System.out.println(I.byteValue()); // Output: -126
System.out.println(I.shortValue()); // Output: 130
System.out.println(I.intValue()); // Output: 130
System.out.println(I.longValue()); // Output: 130
System.out.println(I.floatValue()); // Output: 130.0
System.out.println(I.doubleValue()); // Output: 130.0
These methods allow us to obtain the primitive values (byte, short, int, long, float, double) from the given wrapper object.
charValue()
:- The
charValue()
method is available in the Character class to get the char primitive value for a given character object. - Method Signature: public char charValue()
- The
Character ch = new Character('a');
char c = ch.charValue();
System.out.println(c); // Output: 'a'
This method allows us to obtain the char primitive value from the given character object.
- booleanValue():
- The
booleanValue()
method is available in the Boolean class to get the boolean primitive value for the given Boolean object. - Method Signature: public boolean booleanValue()
- The
Boolean B = Boolean.valueOf("softAai");
boolean b = B.booleanValue();
System.out.println(b); // Output: false
This method allows us to obtain the boolean primitive value from the given Boolean object.
In total, there are 38 (6*6 + 1 + 1
) xxxValue()
methods present.
Wrapper Object ———————— xxxValue()
———————-> Primitive Value
3. parseXxx()
We can use parseXxx()
methods to convert a String to a primitive.
String ——————- parseXxx() ———————-> primitive
Form 1:
Every wrapper class except the Character class contains the following parseXxx()
method to find the primitive for the given String object.
public static primitive parseXxx(String s);
int i = Integer.parseInt("10");
double d = Double.parseDouble("10.5");
boolean b = Boolean.parseBoolean("true");
Form 2:
Every integer wrapper class (Byte, Short, Integer, Long) contains the following parseXxx()
method to convert a specified radix String to a primitive. The allowed range of radix is 2 to 36.
public static primitive parseXxx(String s, int radix);
int i = Integer.parseInt("1111", 2);
System.out.println(i); // Output: 15
4. toString()
We can use toString()
to convert a wrapper object or primitive to a String.
Form 1
Every wrapper class contains the following toString()
method to convert a wrapper object to a String type.
public String toString();
It is an overriding version of the toString()
method in the Object class. Whenever we try to print a Wrapper class reference, internally this toString()
method will be called.
Integer I = new Integer(10);
String s = I.toString();
System.out.println(s); // Output: "10"
System.out.println(I); // internally calls I.toString(), Output: "10"
Wrapper Object ——————- toString()
———————-> String
Form 2
Every wrapper class, including the Character class, contains the following static toString()
method to convert a primitive value to a String type.
public static String toString(primitive p)
String s = Integer.toString(10);
String s = Boolean.toString(true);
String s = Character.toString('a');
This method is particularly useful when you need to convert a primitive value to a String without creating an object of the corresponding wrapper class.
Primitive Value ——————- toString()
———————-> String
Form 3
Integer and Long classes contain the following static toString()
method to convert a primitive to a radix String.
public static String toString(primitive p, int radix);
The allowed radix range is from 2 to 36.
String s = Integer.toString(15, 2);
System.out.println(s); // Output: "1111"
This method is particularly useful when you need to convert a primitive value to a String representation in a specific radix (base).
Form 4
Integer and Long wrapper classes contain the following toXxxString()
methods to convert a primitive to a String in binary, octal, and hexadecimal form.
public static String toBinaryString(primitive p);
public static String toOctalString(primitive p);
public static String toHexString(primitive p);
String s = Integer.toBinaryString(10);
System.out.println(s); // Output: "1010"
String s = Integer.toOctalString(10);
System.out.println(s); // Output: "12"
String s = Integer.toHexString(10);
System.out.println(s); // Output: "a"
These methods allow you to obtain a string representation of the given primitive value in binary, octal, or hexadecimal form. They are particularly useful for formatting output or performing bitwise operations.
Wrapper Object / Primitive ———————- toString()
—————————–> String
Conversions between String, WrapperObject, and Primitive
Wrapper Object to String:
- Using
toString()
: Converts a wrapper object to a String.
Wrapper Object ----------------- toString --------------------> String
Wrapper Object to Primitive Value:
- Using
XxxValue()
: Extracts the primitive value from a wrapper object.
Wrapper Object ------------------ XxxValues() ---------------------> Primitive Value
String to Primitive Value:
- Using
parseXxx()
: Converts a String to a primitive value.
String ------------------------- parseXxx() -------------------------> Primitive Value
String to Wrapper Object:
- Using
valueOf()
: Converts a String to a wrapper object.
String -------------------------- valueOf() -----------------------------> Wrapper Object
Primitive Value to Wrapper Object:
- Using
valueOf()
: Converts a primitive value to a wrapper object.
Primitive Value ---------------- valueOf() ----------------> Wrapper Object
Primitive Value to String:
Using toString()
: Converts a primitive value to a String.
Primitive Value ----------------- toString() --------------------> String
Here we saw various conversions between String, Wrapper Object, and Primitive Value in Java. Each step serves a specific purpose and facilitates flexible data manipulation within the Java ecosystem.
Partial Hierarchy of java.lang package
- Object:
- String, StringBuffer, StringBuilder, Number, Boolean, Character, Void, …
- Number:
- Byte, Short, Integer, Long, Float, Double
Object ──┬─ String
├─ StringBuffer
├─ StringBuilder
├─ Number ──┬─ Byte
│ ├─ Short
│ ├─ Integer
│ ├─ Long
│ ├─ Float
│ └─ Double
├─ Boolean
├─ Character
└─ Void
Conclusions:
- Wrapper classes which are not child classes of Number are Boolean and Character.
- Wrapper classes which are not direct child classes of Object are Byte, Short, Integer, Long, Float, Double.
- Final wrapper classes are String, StringBuffer, and StringBuilder.
- In addition to the String class, all wrapper class objects are also immutable.
- Sometimes Void class is also considered a wrapper class.
Void class
- It is a final class and is the direct child class of Object. It doesn’t contain any methods and contains only one variable, Void.TYPE.
- In general, we can use the Void class in reflection to check whether any method return type is void or not.
if(getMethod("m1").getReturnType() == Void.TYPE)
Void is the class representation of the void keyword in Java.
Conclusion
Wrapper classes in the java.lang
package play a crucial role in Java programming, providing a bridge between primitive types and objects. They offer a range of features and utilities, including conversion, nullability, and seamless integration with collections and generics. While wrapper classes enhance the flexibility and expressiveness of Java code, developers should be mindful of their performance implications in certain contexts. By understanding the nuances of wrapper classes, developers can leverage them effectively to write robust and maintainable Java applications.
In conclusion, wrapper classes are integral components of the Java language, empowering developers to work with primitive types in an object-oriented manner. Their versatility and utility make them indispensable in various programming scenarios, enriching the Java ecosystem with enhanced expressiveness and functionality.