Wrapper Classes in Java

quiz
Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Overview

Wrapper classes in Java provides a way to wrap or represent the value of primitive data types as an object. By creating an object to the wrapper class, a data field is created and in this field we can store the value of a primitive data type.

It also include methods to unwrap the objects back into the primitive data types. It is one of the classes provided in the java.lang package and all of the primitive wrapper classes in Java are immutable.

Scope

This article aims to:

  • Discuss the concept of Wrapper classes in Java
  • Explain the need of Wrapper classes in Java
  • Illustrate how to convert from primitive data type to wrapper class instance and vice versa
  • Mention the advantages of using Wrapper classes in Java Applications

Primitive Data Types

Primitive Data Types acts as the basic building blocks of data manipulation in Java. But for better understanding about the Wrapper classes, let us first understand what are the Data Types and specifically Primitive Data Types.

As Java is a statically-typed programming language which means that any variable can not be used without its declaration. They must be declared first before they can be used.

So, for declaring the variables we use data types. Data type is basically the type of a variable which determines the value it may contain and the operations that may be performed on it.

Data Types in Java

Data types in Java are divided into the following two categories:

  1. Primitive Data Types: The Primitive data types are in-built or predefined in Java. The eight Primitive Data Types include byte, short, int, long, float, double and char. This is predefined by the language and is named by a reserved keyword.

  2. Non-Primitive Data Types: The Non-Primitive Data types are created by the programmer and are not predefined in Java (except String). The Non-Primitive Data Types include String, Arrays and Classes, etc.

Primitive data types have a constraint that they can hold data of the same type and have a fixed size depending on the data type. For example, 1 byte can only store whole numbers in the range from -128 to 127. Also, the primitive data types always have a value.

Introduction to Wrapper Classes in Java

We have discussed about the Primitive Data Types in earlier section. Since the Primitive Data Types cannot be directly used as objects that's why Wrapper classes come into picture.

Generic classes work with objects and don't support Primitives. As a result, Wrapper classes are needed as they convert primitive data types into objects and objects are really important if we need to modify the arguments passed in a method. Now, let's discuss in detail about the Wrapper Classes.

The Java programming language provides the java.lang package which has classes that are fundamental to the design and the most important classes among them are Object and Class.

So, Java wrapper classes wraps or represents the values of primitive data types as an object. When an object is created to a wrapper class, it contains a field which can store the primitive data types.

The object of one type contains a field of that particular type only, which means a Double type of object contains double type of field only, representing that value so that a reference to it can be stored in a variable of reference type.

Below are the Primitive Data Types and their corresponding Wrapper classes:

Primitive Data TypeWrapper Class
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean

Why Do We Need Wrapper Classes in Java?

  • Whenever the primitive types are required as an object, wrapper classes can be used. Wrapper classes also include methods to unwrap the object and give back the primitive data type.
  • In java.util package, the classes handle only objects and that's why in this case wrapper class helps.
  • In the Collection framework, Data Structures such as ArrayList stores only the objects and not the primitive types.
// Invalid
ArrayList<int> exampleList = new ArrayList<>();

// Valid
ArrayList<Integer> exampleList = new ArrayList<>();
  • For the methods that support object like creation from other types such as String.
Integer num = new Integer("55");
  • Wrapper classes are also used for synchronization in multithreading. As objects are needed to achieve the synchronization process where we ensure that the shared resource will be used by only one thread at a time.

Process Flow of the Wrapper Class in Java

Process Flow of the Wrapper Class in Java

In Java Wrapper Classes, the object is created with fields or properties in which the primitive data types can be stored.

Creating Wrapper Objects

Using a Wrapper Class Constructor

We can create a wrapper object using the wrapper class and its constructor by passing the value to it.

Syntax:

ClassName objectName = new ClassName(argument);

Example:

Integer number = new Integer(77); // int
Integer number2 = new Integer("77"); // String
Float number3 = new Float(77.0); // double argument
Float number4 = new Float(77.0f); // float argument
Float number5 = new Float("77.0f"); // String
Character c1 = new Character('S'); // Only char constructor
Character c2 = new Character(1234); // COMPILER ERROR
Boolean b = new Boolean(true); // value stored - true

However, the way of creating an instance of wrapper classes using constructor is deprecated as of the latest version of JDK. This is because each time new memory is allocated in the heap when we create an object with the help of the constructor. Also, the constructor Character(char) has been deprecated since JDK version 9.

Using Wrapper class only (instead of the primitive type)

We can create an instance of wrapper classes without their constructors as well. We can create a variable of data type same as the class name of wrapper classes and assign a raw value to it without using the new operator as shown below:

Syntax:

ClassName objectName = value;

Example 1:

public class CreatingWrapperObject {

  public static void main(String[] args) {
    // Creating the object using the wrapper class
    // without passing the value to the constructor

    // Object intValue of type Integer will store the value 10 as int
    Integer intValue = 10;
    Double doubleValue = 8.89;
    Character charValue = 'S';

    // Printing the values using the created objects
    System.out.println(intValue);
    System.out.println(doubleValue);
    System.out.println(charValue);
  }
}
Output:
10
8.89
S

Example 2: Converting an Integer to a String wrapper class object using the toString() method:

public class CreatingWrapperObject2 {

  public static void main(String[] args) {
    // Creating the object using the Wrapper class
    Integer intValue = 1000;

    // Converting the integer value to String and 
    // assigning it to stringObject
    String stringObject = intValue.toString();

    // Printing the length of the String using length() method
    System.out.println(stringObject.length());
  }
}

Output:

4

Using valueOf Static methods

By using the static valueOf method, a Wrapper object can be created.

Syntax:


ClassName objectName = ClassName.valueOf(argument(s));
// Multiple parameters may be present

Example:

Integer hundred = Integer.valueOf("100");
// 100 is stored in variable. Here, Integer.valueOf(String str) is used.

Integer seven = Integer.valueOf("111", 2);
// binary 111 is converted to 7. 
// Here, Integer.valueOf(String str, int base) is used.

Note:

The difference in using the other methods and valueOf() static method is - By using the Constructor or Wrapper Class method we will always create a new object which will allocate a new memory in the heap each time, while using valueOf() static method, it may return a cached value.

Features of Java Wrapper Classes

Value modification in function:

We have the 'call by value' function in Java programming, using this we can modify the arguments passed into a method with the help of the objects converted from primitive data types. If the argument is not constant and it needs to be modified, we can pass the objects and can modify the values accordingly.

Synchronization

To support Java synchronization an object is needed. It operates into objects in multi-threading. As for the identification of the blocks in multi-threading, objects are required.

Synchronized blocks in Java are marked with the synchronized keyword. This block in Java is synchronized on some object. All blocks that are synchronized on the same object can only have one thread executing inside them at a time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.

Serialisation

To implement the serialisation, the object is converted within streams. The object can be regerated using the java wrapper classes. Basically, the class of the object must implement Serializable interace directly or indirectly.

java.util package

The implementaton of the utility classes in the **java.util **package is to match with the objects and wrapper classes help to achieve the same as well.

Collection framework

Java collection framework classes such as ArrayList, HashSet, Vector, LinkedList, etc. store only objects i.e. reference types and not primitive types. So objects are instances of wrapper classes and that's why it helps for this.

Methods Supported by the Wrapper Classes

All of the numeric wrapper classes are subclasses of the abstract class Number such as Byte, Integer, Double, Short, Float, Long.

Some of the frequently used methods that all subclasses of the Number class implements are listed in the following table:

MethodMethod Description
typeValue()Converts the value of a Numeric object such as Integer, Float or Double to the specified primitive data type and returns the value
compareTo()Compares this Number object to the argument passed
equals()Determines whether this Number object is equal to the argument
valueOf()Returns an Integer object holding the value of the specified primitive data type value
toString() Returns a String object representing the value of specified Integer type argument
parseInt()Returns an Integer type value of a specified String representation
decode()Decodes a String into an integer
min()Returns the smaller value after comparison of the two arguments
max()Returns the larger value after comparison of the two arguments
round()Returns the closest round off long or int value as per the method return type

There are more such methods which are implemented by the subclasses of the Number class. The above table lists only few of them.

Autoboxing

Autoboxing is when the Java compiler performs the automatic conversion of the primitive data types to the object of their corresponding wrapper classes. For example, converting an int to Integer, a double to Double, etc.

The Java compiler applies autoboxing when a primitive value is:

  • Passed as a parameter to a method that expects an object of the corresponding wrapper class.
  • Assigned to a variable of the corresponding wrapper class.

For example:

//Autoboxing example of int to Integer and char to Char

public class AutoboxingExample {

  public static void main(String args[]) {
    char ch = 's';

    //Autoboxing- primitive to Character object conversion
    Character s = ch;

    int a = 50;

    // Converting int into Integer explicitly
    Integer first = Integer.valueOf(a);

    // Autoboxing, now compiler will write Integer.valueOf(a) 
    // internally and hence, doesn't generate an error
    Integer second = a;

    System.out.println(a);
    System.out.println(first);
    System.out.println(second);
  }
}

Output:


50 
50 
50

Explanation:

Here, the output is 50 for all as:

  • The a variable is assigned to int value 50.
  • The first variable is assigned to the value of a that is 50. Only in such a case, primitive data type int is converted into Integer explicitly.
  • The second variable will also have the value of a that is 50 as due to autoboxing the compiler internally performs the conversion automatically (implicit conversion).

Unboxing

It is just the opposite process of autoboxing. Unboxing is automatically converting an object of a wrapper type (Integer, for example) to its corresponding primitive (int) value.

The Java compiler applies unboxing when an object of a wrapper class is:

  • Passed as a parameter to a method that expects a value of the corresponding primitive type.
  • Assigned to a variable of the corresponding primitive type.

For example:

//Unboxing example of Integer to int and Character to char
public class UnboxingExample {

  public static void main(String args[]) {
    Character ch = 's';

    //Unboxing - Character object to primitive conversion
    char s = ch;

    Integer a = new Integer(5);

    //Converting Integer to int explicitly
    int first = a.intValue();

    //Unboxing, now compiler will write a.intValue() internally
    int second = a;

    System.out.println(a);
    System.out.println(first);
    System.out.println(second);
  }
}    

Output:

5 
5 
5

Explanation:

Here, the output for all is 5 as:

  • The object a is created with Integer passing the value 5.
  • The first variable is assigned with a.intValue(). The value of a is 5 so value of first will be 5.
  • The second variable is assigned directly to a. Due to unboxing, the compiler internally assigns the integer value of a that is 5 to second.

Java Wrapper classes Example

1. Primitive Types to Wrapper Objects

class Main {
  public static void main(String[] args) {

    // create primitive types
    int a = 5;
    double b = 5.65;

    //converts into wrapper objects
    Integer aObj = Integer.valueOf(a);
    Double bObj = Double.valueOf(b);

    if(aObj instanceof Integer) {
      System.out.println("An object of Integer is created.");
    }

    if(bObj instanceof Double) {
      System.out.println("An object of Double is created.");
    }
  }
}

Output:

An object of Integer is created.
An object of Double is created.

Explanation:

In the above example, we have used the valueOf() method to convert the primitive types into objects.

Here, we have used the instanceof operator to check whether the generated objects are of Integer or Double type or not.

However, the Java compiler can directly convert the primitive types into corresponding objects. For example,

int a = 5;
// converts into object
Integer aObj = a;

double b = 5.6;
// converts into object
Double bObj = b;

This process is known as auto-boxing which we have already discussed. In which the conversion happens for primitive types into objects internally. Like here in the above example, the primitive type value of a is converted into object aObj. Internally, the Integer.valueOf(a) is used by the compiler and aObj is assigned to the value of a that is 5.

2. Wrapper Objects into Primitive Types

class Main {
  public static void main(String[] args) {

    // creates objects of wrapper class
    Integer aObj = Integer.valueOf(23);
    Double bObj = Double.valueOf(5.55);

    // converts into primitive types
    int a = aObj.intValue();
    double b = bObj.doubleValue();

    System.out.println("The value of a: " + a);
    System.out.println("The value of b: " + b);
  }
}

Output:

The value of a: 23
The value of b: 5.55

Explanation:

In the above example, we have used the intValue() and doubleValue() method to convert the Integer and Double objects into corresponding primitive types.

However, the Java compiler can automatically convert objects into corresponding primitive types. For example,

Integer aObj = Integer.valueOf(2);
// converts into int type
int a = aObj;

Double bObj = Double.valueOf(5.55);
// converts into double type
double b = bObj;

This process is known as unboxing which we have already discussed.

Custom Wrapper Class in Java.

As the Java Wrapper classes wrap the primitive data types. Likewise, we can also create custom wrapper class in Java which wraps a primitive data type.

// Creating the custom wrapper class
class SpeedWrapperClass {

  private int speed;

  SpeedWrapperClass() {}

  SpeedWrapperClass(int speed) {
    this.speed = speed;
  }

  public int getVehicleSpeed() {
    return speed;
  }

  public void setVehicleSpeed(int speed) {
    this.speed = speed;
  }

  @Override
  public String toString() {
    return Integer.toString(speed);
  }
}

// Testing the custom wrapper class
public class TestJavaWrapperClass {

  public static void main(String[] args) {
    SpeedWrapperClass speedValue = new SpeedWrapperClass(100);
    System.out.println(speedValue);
  }
}

Output:

100

Explanation:

  • Here, we have created a custom wrapper class that is SpeedWrapperClass() and to set the value of speed we have also created constructors.
  • Now, when we created an instance of the custom wrapper class and passed the integer value it worked as Integer wrapper class which wraps the int value of 100 and set the speed as 100.
  • In a way, we have a data member field of type int speed which holds the primitve int value passed as argument to the constructor.

Advantages of Java Wrapper Class in Java

  • In Java, there can be various scenarios where we need to use objects instead of primitive data types. For example, while working with collections. As we can see in the below example we need to use Integer not the primitive int.
// error
ArrayList<int> list = new ArrayList<>();

// runs perfectly
ArrayList<Integer> list = new ArrayList<>()
  • We can use the objects of the wrapper class and store them as a null value. In real time scenario applications, the values can be null and hence, we need to store null values.
  • Objects of classes such as Character and Integer are pointers: the actual number stored in the bytes that are that reference variable's value represents an address in memory.
  • So, it is possible and meaningful to set that number to an address that goes nowhere. This is exactly what null is.
  • A primitive like int or char, however, has a number that is interpreted as a number (integer, or ASCII code), and there's no way to make it "not a number" because all that the memory can possibly store is numbers.

// generates an error
int a = null;

// runs perfectly
// More intuitive in real world applications
Integer a = null;
  • A wrapper type allows a primitive to operate in more advanced ways. An integer can be used in various ways. For example, we can create a class Hour which will give a meaning to the number associated with it.
  • The primitive types just operate with value, the wrapper class provides it with a name. For example, int as Integer, char as Character, etc. It means that int only specifies the range and type of the value but by creating the object with wrapper class Integer it will be given a reference variable which points to the object in the heap memory.

Conclusion.

  • Wrapper classes in Java wraps the primitive data type in its class object.
  • Java wrapper classes are provided in the java.lang package.
  • In the Java Collection Framework, Data Structures such as ArrayList stores only the objects and not the primitive types.
  • Autoboxing and unboxing converts the primitive data types into objects and objects into primitives respectively.
  • Instances of wrapper classes can prove to be useful in many scenarios such as in synchronization, serialisation, collections, etc.
  • We can assign a Integer class object to null, however the same is not valid with int primitive data type.
  • We can also create custom Wrapper classes which wraps a primitive data type of our choice.
Challenge Time!
quiz
quiz
Time to test your skills and win rewards! Note: Rewards will be credited after the next product update.
Free Courses by top Scaler instructors
certificate icon
Certificates
Java Tutorial
This program includes modules that cover the basics to advance constructs of Java Tutorial. The highly interactive and curated modules are designed to help you become a master of this language.'
If you’re a learning enthusiast, this is for you.
Module Certificate
Criteria
Upon successful completion of all the modules in the hub, you will be eligible for a certificate.
You need to sign in, in the beginning, to track your progress and get your certificate.
rcbGet a Free personalized Career Roadmap from