Wrapper Class Java Example
1. What is a wrapper class
A wrapper class in Java is a way to convert a primitive data type such as boolean, int, etc. into an object. Also, we can convert an object of a wrapper class into its corresponding primitive type.
In this article we are going to talk about why we need wrapper classes, autoboxing, and autounboxing. In addition, we will show you an example of creating and using a custom wrapper in Java.
The JDK version we use to compile the source code in this example is OpenJDK 13 and the IDE we use is Eclipse IDE 2020-03.
2. Why do we need wrapper classes?
Fundamentally Java is an object-oriented programming language and treats everything as an object. But primitive data types are not objects. They are built-in features of the Java language itself and they don’t belong to any class in any package. Several features provided by Java such as inheritance, polymorphism, and generics cannot deal with primitive data types directly but objects. For example, the Java collection framework we use very often works with objects only.
Furthermore, from a Clean Code perspective and by following coding best practices, a wrapper class lets developers write cleaner code, making it easier to read.
3. Primitive and corresponding wrapper class
The following table lists eight primitive types and their corresponding wrapper classes. These wrapper classes are part of java.lang
package so the package name is omitted.
Primitive Type | Wrapper Class |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
4. Autoboxing
Autoboxing conversion, converts primitive type to its corresponding wrapper class. In the following scenarios, the autoboxing will be applied by the Java compiler:
- A primitive is passed as a parameter to a method that expects an object of the corresponding wrapper class.
- A primitivee is assigned to a variable of the corresponding wrapper class.
public class AutoboxingExample { /** * @param args */ public static void main(String[] args) { // passing an int to a method expecting an Integer Integer result = plusOne(7); // print the result to standard output System.out.printf("7 + 1 = %d\n", result); // primitive variable int c = 100; // autoboxing converting int to Integer Integer count = c; System.out.printf("The count is %d\n", count); } private static Integer plusOne(Integer count) { return count + 1; } }
5. Autounboxing
Autounboxing, converts an object of a wrapper to its corresponding primitive value. In the following scenarios, the autounboxing will be applied by the Java compiler:
- An object of a wrapper is passed as a parameter to a method that expects a value of the corresponding primitive type.
- An object of a wrapper is assigned to a variable of the corresponding primitive type.
public class AutounboxingExample { /** * @param args */ public static void main(String[] args) { // passing an Integer to a method expecting an int Integer integer = new Integer(7); int result = plusOne(integer); // print the result to standard output System.out.printf("7 + 1 = %d\n", result); // wrapper class variable Integer c = new Integer(100); // autounboxing converting Integer to int int count = c; System.out.printf("The count is %d\n", count); } private static int plusOne(int count) { return count + 1; } }
6. A custom wrapper class Java example
Imagining we are working on an e-commerce website project and we need to get a new user’s age from the sign-up page. And also we need to read an existing user’s age from the database. What do these requirements mean? The age from user input on the sign-up page will be a text string. But the age read from the database normally is a primitive integer. Is it possible to design a Java class to handle both correctly? The answer is yes and a custom wrapper comes into play.
In the example below, we define a class Age
. In addition to the default constructor, we define another constructor accepting a primitive int parameter. Also we define a static factory method valueOf
which accepts a primitive int parameter and returns a new Age instance with the given value. To handle an age of String type, we can simply define another static factory method valueOf
which accepts a String parameter and returns a new Age instance.
/** * A custom wrapper class represents Age. */ public class Age { // the variable holds the primitive age value private final int value; /** * Constructor. * * @param age */ public Age(int age) { this.value = age; } /** * Returns an {@code Age} object holding the value of the specified {@code int}. * * @param age the age integer to be parsed. * @return an {@code Age} object holding the value represented by the integer argument. */ public static Age valueOf(int age) { return new Age(age); } /** * Returns an {@code Age} object holding the value of the specified * {@code String}. * * @param age the age string to be parsed. * @return an {@code Age} object holding the value represented by the String argument. */ public static Age valueOf(String age) { return new Age(Integer.valueOf(age)); } /** * @return the value */ public int intValue() { return value; } @Override public String toString() { return Integer.toString(value); } }
Now let’s see how to use the Age
class we just defined.
public class CustomWrapperClassExample { /** * @param args */ public static void main(String[] args) { // create an Age instance from its constructor Age age10 = new Age(10); // print the age to standard output using its int value System.out.printf("My younger brother is %d years old\n", age10.intValue()); // create an Age instance from a static factory method accepting int parameter Age age20 = Age.valueOf(20); // print the age to standard output using its int value System.out.printf("I am %d years old\n", age20.intValue()); // create an Age instance from a static factory method accepting String parameter Age age30 = Age.valueOf("30"); // print the age to standard output using its String value System.out.println("My older sister's age is " + age30.toString()); } /** * Private static internal class for demo purpose. */ private static class Age { // the variable holds the primitive age value private final int value; /** * Constructor. * * @param age */ public Age(int age) { this.value = age; } /** * Returns an {@code Age} object holding the value of the specified {@code int}. * * @param age the age integer to be parsed. * @return an {@code Age} object holding the value represented by the integer argument. */ public static Age valueOf(int age) { return new Age(age); } /** * Returns an {@code Age} object holding the value of the specified * {@code String}. * * @param age the age string to be parsed. * @return an {@code Age} object holding the value represented by the String argument. */ public static Age valueOf(String age) { return new Age(Integer.valueOf(age)); } /** * @return the value */ public int intValue() { return value; } @Override public String toString() { return Integer.toString(value); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + value; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Age other = (Age) obj; if (value != other.value) return false; return true; } } }
Is it possible for the Java compiler to apply autoboxing and autounboxing? Let’s have a try:
// Autoboxing for custom wrapper is not supported in Java Age age0 = 0;
When we try to compile, it will fail with the following error message:
Type mismatch: cannot convert from int to Age.
So autoboxing and auto unboxing are not supported.
7. Download the Source Code
You can download the full source code of this example here: Wrapper Class Java Example