In the below class I have tried to compare the wrapper class with the primitive but the results are different.
I have checked the following links links:
The more interesting question is why
new Object();
should be required to create a unique instance every time? i. e. why isnew Object();
not allowed to cache? The answer is thewait(...)
andnotify(...)
calls. Caching newObject()
s would incorrectly cause threads to synchronize with each other when they shouldn't.
If there is a new object then how are a
and c
equal?
If b
is equal to c
and c
is equal to a
, then a
should be equal to b
. But in following case I got a != c
.
Please explain.
class WrapperCompare { public static void main (String args[]) { Integer a = new Integer(10); Integer b = 10; int c=10; System.out.println(b==c); //true System.out.println(a==b); //false System.out.println(a==c); //true } }
Update: By referring to this link Integer caching.
Basically, the Integer class keeps a cache of Integer instances in the range of -128 to 127, and all autoboxing, literals and uses of Integer.valueOf() will return instances from that cache for the range it covers.
So in this case all statements should be true.
Java Integer Cache Implementation: In Java 5, a new feature was introduced to save the memory and improve performance for Integer type objects handling. Integer objects are cached internally and reused via the same referenced objects. This is applicable for Integer values in the range between –128 to +127.
By default, these values will be from -128 to 127. So, for any number you pass between -128 and 127 (inclusive), it doesn't create the new Integer object. Instead it returns already cached object from the array.
The java. lang. Integer. valueOf(String s, int radix) is an inbuilt method which returns an Integer object, holding the value extracted from the specified String when parsed with the base given by the second argument.
Also known as an integer, int type holds a wide range of non-fractional number values. Specifically, Java stores it using 32 bits of memory. In other words, it can represent values from -2,147,483,648 (-231) to 2,147,483,647 (231-1).
When you compare Integer
vs int
with ==
, it needs to convert the Integer
to an int
. This is called unboxing.
See JLS§5.1.8:
If
r
is a reference of typeInteger
, then unboxing conversion convertsr
intor.intValue()
At that point, you are comparing int
vs int
. And primitives have no notion of instances, they all refer to the same value. As such, the result is true
.
So the actual code you have is
a.intValue() == c
leading to a comparison of 10 == 10
, both int
values, no Integer
instances anymore.
You can see that new Integer(...)
indeed creates new instances, when you compare Integer
vs Integer
. You did that in a == b
.
The constructor new Integer(...)
is deprecated. You should instead use Integer#valueOf
, it is potentially faster and also uses an internal cache. From the documentation:
Returns an
Integer
instance representing the specifiedint
value. If a new Integer instance is not required, this method should generally be used in preference to the constructorInteger(int)
, as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range-128
to127
, inclusive, and may cache other values outside of this range.
The caching is important to note here, since it yields to ==
being true again (for cached values):
Integer first = Integer.valueOf(10); Integer second = Integer.valueOf(10); System.out.println(first == second); // true
The caching is guaranteed for values between -128
and +127
, but may also be used for others.
Also note that your b
actually comes out of the cache, since
Integer b = 10; // same as Integer b = Integer.valueOf(10); // and not Integer b = new Integer(10);
So boxing goes through Integer
s cache (see JLS§5.1.7).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With