• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

'==' operators with Wrapper class

 
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi I m in a little bit of confusion, I m studying Wrapper classes. The problem is with the == operator.

Output: Same Objects
Now here the int values are 100 for both i1&i2, now if I'll change it to 1000 the == operator won't show the same output like

Output: Different Objects
 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
from -128 to 127 , the Integer object compares the values
 
Ranch Hand
Posts: 608
Firefox Browser Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

seetharaman venkatasamy wrote:from -128 to 127 , the Integer object compares the values



That does not sound correct.
The == operator always compares objects on the heap and not values. Hence there is no question of == comparing values.
You can verify this by


In this case the output is different object.

Trying to get to the original question, when we do
Integer i1 = 100; we are using auto boxing to convert the Integer/Short value to an Integer Object. I think the issue happens because of the way Java does the autoboxing though I agree it is weird!

 
pranjal mishra
Greenhorn
Posts: 21
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

seetharaman venkatasamy wrote:from -128 to 127 , the Integer object compares the values


well i think he is right upto some point.
Actually what i have figured out that if i'll assign the values to i1 and i2 till 127 the == will work, as soon as the value crosses 128 it won't work.
so for Short/Integer objects the == will always work if their primitives value will be between -128 to 127;

 
Saifuddin Merchant
Ranch Hand
Posts: 608
Firefox Browser Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Explanation --> http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

Yep I was also a bit caught up, but for a real programming the rule is pretty simple,
Use == only for primitive types and reference equality
Use .equals for everything else!


 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you use Strings and have two Strings which are compile time constants, the JVM uses the same String objectTry that, and you find the two references point to the same String object.

When you use some wrapper objects, something rather similar happens. It happens for Integers; I think it happens for other types but can't remember the details. The JVM sets up a cache of objects for a restricted range of values, in the case of Integer where -128 <= i < 128, and reuses those objects if the same value is requested. So your two Integers for 100 will use the same object, and your two Integers for 1000 won't. The article quoted by Sam Mercs gives a good explanation.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

seetharaman venkatasamy wrote:from -128 to 127 , the Integer object compares the values


No, it does not. But the reason why it seems to be like this, is because of the way that autoboxing and the method Integer.valueOf(int i) work.

First, when you use autoboxing, for example with a statement like this:

This is automatically translated by the Java compiler to the following:

So, when you use autoboxing, you are really implicitly calling the method Integer.valueOf(int i).

Now, the method Integer.valueOf(int i) contains an optimization. It has a cache containing Integer objects for all the values between -128 and 127. If you call the method with an int that is in this range, then the method does not create a new Integer object; instead, it returns one of the existing Integer objects in the cache. Creating a new object is relatively expensive, so using a cache like this makes programs run more efficiently.

That means that if you do something like this:

You are calling Integer.valueOf(int i) two times, with the same value 100, which is in the cache - so the method will return the same Integer object from the cache for both i1 and i2.

Since ==, when used on objects, checks if the two expressions on both sides of the == are the same object, the comparison i1 == i2 will return true.

Note that for numbers not in the range -128 to 127, Integer.valueOf(int i) will return a new Integer object.
 
pranjal mishra
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot Jasper for such a wonderful explanation , Actually i had figured it out that for the range of -128 to 127 it works but what is the reason behind that now you told me.
Thanks a lot once again.
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Excellent Jesper Young
 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thank you Jasper Young.. the reply was very useful
 
Ranch Hand
Posts: 42
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nice answer! I knew about the -128 to 127 but not why!
Thanks
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Gaurav .Singh, welcome to the Ranch
 
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The range is not always the same. You can change it with properties. However it is always at least -128 to 127
 
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
See JLS - Boxing Conversions...

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Wouter Oet wrote:The range is not always the same. You can change it with properties.


Really? Can you tell me which ones then? Because the source of Integer in Java 6 uses an array with hard coded bounds of -128 and 127.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

marc weber wrote:See JLS - Boxing Conversions

I knew it was in the JLS somewhere, but had forgotten where.Thank you.
 
Wouter Oet
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:

Wouter Oet wrote:The range is not always the same. You can change it with properties.


Really? Can you tell me which ones then? Because the source of Integer in Java 6 uses an array with hard coded bounds of -128 and 127.



C:\Users\Wouter\Documents\Temp>javac Test.java

C:\Users\Wouter\Documents\Temp>java Test
false

C:\Users\Wouter\Documents\Temp>java -Djava.lang.Integer.IntegerCache.high=2000 Test
true

Btw. There is no need for cynicism. Even if I where wrong. We're are human and we all make mistakes.
 
Jesper de Jong
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Interesting Wouter, I didn't know you could change the size of the Integer cache by a system property. I've looked in the source code of class Integer, and it does check if the value that you supply is larger than 127; if it's smaller, it's set to 127. So you can only make the cache larger, not smaller, than the standard value 127. (Which is understandable - if it weren't like that, it wouldn't conform to the JLS).
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The JLS page quoted does say that it would be ideal to use a larger cache. Again, I had never seen that property used.
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I believe the property was added recently, so I am not surprised that it is not well known. For some reason, I remember a bug report, requesting this, only last year.

Henry
 
Wouter Oet
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is correct. You're referring to this bug.
 
Jesper de Jong
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Aha, according to the bug report this is a new feature added in Java 6 update 14, so indeed quite recent.
 
Wouter Oet
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What I find weird is that there is no such functionality for longs.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Wouter Oet wrote:Btw. There is no need for cynicism. Even if I where wrong. We're are human and we all make mistakes.


I wasn't being cynical. I was genuinely interested because as I said I couldn't find it in the source code. As Jesper noted it wasn't added until update 14, which explains why the source I used didn't have it.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Wouter Oet wrote:What I find weird is that there is no such functionality for longs.


It isn't present for byte, short or char either. Granted, byte wouldn't even need this functionality, but the others could have benefited from it too.
 
Master Rancher
Posts: 4806
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Interestingly, they seem to have backported this to the latest JDK 5 release as well, though it definitely wasn't in JDK 5 originally either.

As for why it's only in Integer - well, I guess ints are used so much more than any other type, they figured it was much more important to do it for ints than for anything else. Seems like it should have been easy to add it to the others anyway, but they didn't. They also only made it configurable in one direction, which is a little strange. The lower limit remains fixed at -128.

Perhaps each use of a config parameter in startup slows things down a tiny bit. For most applications this is irrelevant, but a few apps would benefit from a faster startup, so Sun/Oracle didn't want to slow these more than necessary. Though this still seems like the effect would be insignificant for current JVMs, note that Project Jigsaw is supposed to allow for faster startup of some apps (with fewer things to initialize). So maybe Sun/Oracle thought now would be a bad time to add to startup time in other areas.

Also of interest - longs aren't even required to be cached at all, but they do it anyway. Maybe it's an experiment that they didn't want to commit to. My guess is if a number is big enough that it requires a long, the chance that caching will help it is much lower than if it's an int. Sometimes it will help, sure, but I think it's another thing where they estimate the probable costs to probable benefits, and caching longs just isn't all that useful. Configuring the cache, even less so.
 
Wouter Oet
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:

Wouter Oet wrote:What I find weird is that there is no such functionality for longs.


It isn't present for byte, short or char either. Granted, byte wouldn't even need this functionality, but the others could have benefited from it too.


It is present for Byte. However due to a bad implementation not all the methods use this cache.
 
Mike Simmons
Master Rancher
Posts: 4806
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hm, I thought the "it" Rob referred to was the new functionality of the cache being configurable. And as far as I can see, it isn't configurable. Now would there be any reason to make it configurable - the JLS already requires the cache to cover the full range of byte, so what else could you configure it to? I'm looking at java.lang.Byte.ByteCache.cache, which is final, and initialized to "new Byte[-(-128) + 127 + 1];" Are you talking about something else?
 
Wouter Oet
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm talking about the cache itself. Not if it's configurable. The methods valueOf(String s) and valueOf(String s, int radix) of the Byte class do not use this cache which is a shame because autoboxing uses the first method.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This was also the case for Integer in the early updates of Java 6. There was clearly a "new Integer" in the other valueOf methods.

I did a file comparison of Byte's source of the latest update (19) and the previous version I had, with the old Integer source, and the two files are 100% identical. Long has changed so far as to use valueOf(long) in the other valueOf methods, but apart from Byte, Short and Character are also 100% identical.
 
Mike Simmons
Master Rancher
Posts: 4806
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Wouter Oet wrote:I'm talking about the cache itself. Not if it's configurable.


In that case, there is such functionality for longs. It's right there in the Long class, in the valueOf(long) method which is used by autoboxing. It's not described in the JLS, but then, neither is the configurability.
 
Wouter Oet
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're correct, I misinterpreted it. I look at the source code and a cache is also available for Character and Short.
reply
    Bookmark Topic Watch Topic
  • New Topic