view content/Java/autoboxing.md @ 103:6aa2fa328a94

New blog post on sonar and maven
author Dirk Olmes <dirk.olmes@codedo.de>
date Tue, 12 May 2020 08:30:22 +0200
parents 57988fb9567c
children
line wrap: on
line source

Title: Autoboxing? not for me!
Date: 2011-09-16
Tags: JDK
Lang: en

Autoboxing appeared first with JDK5 and lots of people go crazy about it. At first look it's a nice feature but the more you play with it the more I'm coming to the conclusion that the autoboxing implementation just sucks.

I will not rant about autoboxing pitfalls [that others have described already](https://effective-java.com/2010/05/the-advantages-and-traps-of-autoboxing/) but instead I'd like to point out my favourite autoboxing fail that alone is the reason not to use it: the `IntegerCache`.

Consider this code snippet:

    :::java
    Integer value = 1;
    Integer anotherValue = 1;
    System.out.println(value == anotherValue);

This is true, right? So let's change it just a bit:

    :::java
    Integer value = 128;
    Integer anotherValue = 128;
    System.out.println(value == anotherValue);

This time it's false. What? 128 != 128? Can't be.

Well this is autoboxing in action. You are not comparing plain int values as one would expect at first glance. Instead you are comparing `Integer` instances and we all know that comparing object instances via the == operator only if both sides of the term refer to the same object.

The compiler basically rewrites the code snippet above to:

    :::java
    Integer value = Integer.valueOf(128);
    Integer anotherValue = Integer.valueOf(128);
    System.out.println(value == anotherValue);

Now go and have a look at Integer's implementation of `Integer.valueOf(int)`. You'll see that it uses an `IntegerCache` internally that is used to cache instances of `Integer` - but only for a certain range of numbers.

In the first code snippet where value was 1 the `IntegerCache` was used and the same (cached) instance was returned. In the second code snippet I chose a value that's just outside of the cache range. This time we compare two different instances and hence the comparison fails.

Now imagine you have to sift through some legacy code where the variable declaration is not right above the comparison but some 100 lines above. Would you be able to tell why the comparison fails at first glance? I wouldn't and that's why I avoid Java's autoboxing at all cost.