This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
In Chapter 3, p236 of K & B SCJP 1.5 Certification Text has the following excerpt. Can you tell me how the JVM saves memory with this feature implementation? Thanks.
Produces the output:
This example produces the output:
Yikes! The equals() method seems to be working, but what happened with ==
and != ? Why is != telling us that i1 and i2 are different objects, when == is saying
that i3 and i4 are the same object? In order to save memory, two instances of the
following wrapper objects will always be == when their primitive values are the same:
-- Character from \u0000 to \u007f (7f is 127 in decimal)
-- Short and Integer from -128 to 127
From K & B SCJP Certification Text Errata, the following is abstracted:
236....clarify...Sentence before bullet points s/b: In order to save memory, two instances of the following wrapper objects, created through autoboxing, will always be equal...
Because they're the same objects there's only one object instead of two.
Joined: Jun 17, 2009
How can i3 and i4 be the same object when I instantiated them separately? i3 is a reference to one object, and i4 is a reference to a different object. They are meaningfully equal. I think I see the reason now, but it isn't that obvious. After incrementing i3, it points to a different wrapper object.
How can i3 and i4 be the same object when I instantiated them separately? i3 is a reference to one object, and i4 is a reference to a different object. They are meaningfully equal.
But you did *not* instantiate i3 and i4. You declared i3 and i4. And you used autoboxing to "create" the object. Autoboxing uses the valueOf() method, which may instantiate a new object, or may get you a copy from an internal cache.
i3 & i4 assigned values fall with in -128 - 127 and their primitive values same hence i3 == i4.
Joined: Jun 17, 2009
i3 is a reference to an Integer object, not an int primitive.
i4 is also a reference to an Integer object, not an int primitive.
Integer is a wrapper class.
i3 and i4 are references to the same object, an Integer wrapper object that wraps a primitive with a value of 10. Because i3 and i4 are referencing the same object, the JVM saves memory. Because i3 and i4 are referencing the same object, i3==i4.
Autoboxing works like this: If you write a line such as:
The compiler will automatically convert this to:
Now, the implementation of class Integer contains something smart to avoid making a lot of Integer objects for often used values. Class Integer has a cache of Integer objects, which represent all the values between -128 and 127. When you call the valueOf() method, it first looks if the value that you pass in is between -128 and 127. If it is, then it returns an Integer object from the cache; otherwise, it creates a new Integer object with the value you specified.
If you do something like this:
This will be converted to:
In both these lines, valueOf() will return the same Integer object from its cache. If you compare i3 with i4 by using ==, you will get 'true', because they refer to the same Integer object.
If you would use a value outside the range -128 to 127 instead of 10, the result would be 'false'.