DEV Community

Cover image for Wrapper classes and caching pitfalls
BOUFATAH Amine
BOUFATAH Amine

Posted on • Edited on

Wrapper classes and caching pitfalls

Wrapper Classes

As you all know, the Java language comes up with Primitive Wrapper classes (Integer for int, Double for double, Long for long, Character for char and so on).

Wrapper classes provide a way to use primitive data types (int, boolean, etc..) as objects.

Wrapper classes are immutable just like Strings and most Java Developers ignore that just like String objects these wrapper classes have also their own constant pool and that's tricky...

The problem

Consider the following method:

Equals method

And now the main method:

Main method

Can you guess the program's output after launching the main method?

If your answer was:

1==1 ? true
1==2 ? false
127==127 ? true
128==128 ? true

Then unfortunately you got it wrong in the last one. Here's the right answer:

1==1 ? true
1==2 ? false
127==127 ? true
128==128 ? false

Surprise!!!

What happened?

The problem is that an Integer is an object and because we are using the == operator, we are comparing references in the heap here and not actual values.

You may reply: "Okay but then why does the program print out true in the case of 1==1?". Alright let me explain that for you in a simple way, when you write the following code:

Code

The compiler transforms it to this code behind the scenes:

Code

This is called Autoboxing.

Autoboxing/Unboxing

It's a mechanism used by the compiler to transform automatically wrapper classes to their primitive types (autoboxing) and the other way around (unboxing).

When we call the equals method like the following equals(1,1), the compiler is smart enough to notice that the equals method takes 2 Integer objects as parameters and not primitives, that's when Autoboxing happens, the compiler transforms your primitive data type (int) into a wrapper object (Integer) by calling the valueOf() method.

Okay, so there must be something going on under the valueOf() method. Let's have a look:

Code

As you can see this method caches objects that have values between -128 and 127. This basically means that whenever we ask for an Integer between these values Java will always provide the same instance and that's the reason why 1==1 renders true and 128 == 128 renders false.

Best practice

The best practice here in order to test the equality of wrapper classes is to use the equals() method which compares object values rather than object references in the heap.

Top comments (1)

Collapse
 
ghdbe profile image
GhdbE

Thanks Sir !!