annotate content/Java/autoboxing.md @ 71:6e8d97e43bd7

Automated merge with ssh://xanthippe//home/dirk/Projekte/Blog
author Dirk Olmes <dirk@xanthippe.ping.de>
date Sat, 02 Jan 2016 03:18:12 +0100
parents 4cd9b65e10e4
children 57988fb9567c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
1 Title: Autoboxing? not for me!
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
2 Date: 2011-09-16
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
3 Tags: JDK
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
4 Lang: en
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
5
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
6 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.
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
7
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
8 I will not rant about autoboxing pitfalls [that others have described already](http://www.certpal.com/blogs/2009/08/autoboxing-unboxing-gotchas/) but instead I'd like to point out my favourite autoboxing fail that alone is the reason not to use it: the `IntegerCache`.
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
9
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
10 Consider this code snippet:
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
11
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
12 :::java
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
13 Integer value = 1;
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
14 Integer anotherValue = 1;
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
15 System.out.println(value == anotherValue);
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
16
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
17 This is true, right? So let's change it just a bit:
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
18
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
19 :::java
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
20 Integer value = 128;
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
21 Integer anotherValue = 128;
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
22 System.out.println(value == anotherValue);
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
23
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
24 This time it's false. What? 128 != 128? Can't be.
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
25
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
26 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.
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
27
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
28 The compiler basically rewrites the code snippet above to:
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
29
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
30 :::java
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
31 Integer value = Integer.valueOf(128);
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
32 Integer anotherValue = Integer.valueOf(128);
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
33 System.out.println(value == anotherValue);
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
34
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
35 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.
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
36
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
37 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.
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
38
4cd9b65e10e4 initial import of the pelican based blog
Dirk Olmes <dirk@xanthippe.ping.de>
parents:
diff changeset
39 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.