1. List of wrapper types

You know that Java has 8 primitive types, which are types that are not classes. On the one hand, this is good — they are simple and take up little space. On the other hand, sometimes classes are just what we need. You'll find out exactly why that is in the next lesson.

So what can be done?

Starting with the fifth version of Java, each primitive type gained a twin class. Each such class stores a single field with a value of a specific type. These classes are called wrapper types, because they wrap primitive values in classes.

Here is a list of these types. Do you know any?

Primitive type Wrapper class
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean

The names of primitive types start with a lowercase letter, but the names of the wrapper classes start with an uppercase letter. Some of the class names are also a little longer: Integer against int and Character against char.

All objects of the wrapper classes are unchangeable (immutable).

Simplified code for the Integer class looks something like this:

Code Note
public class Integer
{
   private int value;

   Integer(int x)
   {
      this.value = x;
   }

   public int intValue()
   {
      return this.value;
   }

   public static Integer valueOf(int x)
   {
      return new Integer(x);
   }
}


Variable

Constructor




The method returns a value




The static method creates a new Integer object for an int variable

2. Converting an int to an Integer

Wrapper types are considered counterparts to their primitive siblings: you can easily create a wrapper object that corresponds to a primitive type.

Let's use the int type as an example to analyze how primitive types interact with their corresponding wrapper types. The code for converting from an int to an Integer and vice versa would look like this:

To convert an int to an Integer, you need to write this code:

Integer name = new Integer(value);

Where name is the name of an Integer variable, and value is the wrapped int value.

Examples:

Code Note
Integer age = new Integer(18);
Integer hundred = new Integer(100);
Integer zero = new Integer(0);

And to convert the an Integer to an int, you need to write this code:

int name = variable.intValue();

Where name is the name of an int variable, and variable is a reference to an Integer object.

Examples:

Code Note
Integer age = new Integer(18);
int x = age.intValue();

x == 18
Integer hundred = new Integer(100);
int y = hundred.intValue();

y == 100
Integer zero = new Integer(0);
int z = zero.intValue();


z == 0
int i = 110;
Integer zero = new Integer(i);
int z = zero.intValue();

z == 110

3. Autoboxing and unboxing

But even simple operations with the Integer type are not easy to write.

As we said previously, the Integer type is unchangeable (immutable). To create an Integer object with a new int value, you need to explicitly create a new Integer object. That said, it's easy to get the value of an int stored inside an Integer object — just call the intValue() method.

Example:

Code Description
Integer a = Integer.valueOf(5);
int b = a.intValue();
Integer c = new Integer(b + 5)
Wrap 5 in an Integer object
Get the value from the Integer object
Create a new Integer object (equal to 10)

This is rather cumbersome code, don't you think?

Java's creators thought so, so they taught the compiler how to do these operations automatically. The automatic conversion of an int to an Integer is called autoboxing (automatically putting the value into a box), and the reverse operation (converting an Integer to an int) is called unboxing.

Your code What the compiler sees
Integer a = 10;
Integer a = Integer.valueOf(10);
int b = a;
int b = a.intValue();
Integer c = a + b;
Integer c = Integer.valueOf(a.intValue() + b);

Thanks to autoboxing and unboxing, you can safely assign an int to an Integer variable and vice versa. You can write expressions of any complexity without making a distinction between the int and Integer types.

Examples:

Code What the compiler will generate
Integer a = 5;
int b = a;
Integer c = a + b;
int d = a + b + c;
Integer a = Integer.valueOf(5);
int b = a.intValue();
Integer c = Integer.valueOf(a.intValue() + b);
int d = a.intValue() + b + c.intValue();
Integer a = 5;
int b = 5;

if (a == b)
{
   ...
}
Integer a = Integer.valueOf (5);
int b = 5;

if (a.intValue() == b)
{
   ...
}


4. Comparing wrapper variables

Autoboxing and unboxing are simple and transparent processes. We use new Integer() statements as needed, and we call the intValue() method as needed.

Everything works nice and easy for you, the programmer. Be keep in mind that if you compare an Integer and an Integer, then the comparison is based on reference and not values.

Code Console output
Integer a = 1000;
Integer b = 1000;

System.out.println(a == b);



false
Integer a = 1000;
Integer b = 1000;

System.out.println(a.equals(b));



true

The a and b variables do not store int values. They store references to objects. That means it is important to remember how to compare them correctly:

Wrong Right
Integer a = 1000;
Integer b = 1000;
if (a == b)
{
   ...
}
Integer a = 1000;
Integer b = 1000;
if (a.equals(b))
{
   ...
}