Core Java

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 TypeWrapper Class
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

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

Download
You can download the full source code of this example here: Wrapper Class Java Example

Kevin Yang

A software design and development professional with seventeen years’ experience in the IT industry, especially with Java EE and .NET, I have worked for software companies, scientific research institutes and websites.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button