Mercurial > hg > Blog
annotate content/Java/autoboxing.md @ 67:82ccd2b150af
add a comment
author | Dirk Olmes <dirk@xanthippe.ping.de> |
---|---|
date | Sun, 01 Nov 2015 11:34:06 +0100 |
parents | 4cd9b65e10e4 |
children | 57988fb9567c |
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. |