aspose file tools*
The moose likes Java in General and the fly likes Strange Behaviour Of Wrapper Class Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Strange Behaviour Of Wrapper Class" Watch "Strange Behaviour Of Wrapper Class" New topic
Author

Strange Behaviour Of Wrapper Class

Sanket Meghani
Greenhorn

Joined: Jan 15, 2007
Posts: 14
Hello EveryOne,

I was just playing around the wrapper classes and observed some unexpected behaviour.

public class HelloWorld
{
public static void main( String args[] )
{
Integer i1 = 100;
Integer i2 = 100;

System.out.println( "i1 == i2 : " + ( i1 == i2 ) );
}
}

Output of the above code is unexpected with different values of i1 and i2.

For the current values ( i1 = 100 and i2 = 100 ) the output is : "i1 == i2 : true"

But for the following code,

public class HelloWorld
{
public static void main( String args[] )
{
Integer i1 = 1000;
Integer i2 = 1000;

System.out.println( "i1 == i2 : " + ( i1 == i2 ) );
}
}

the output is "i1 == i2 : false"

From different conbinations I have observed that in the above code for values of i1 and i2 between -128 to 127 ( range of byte ), i1 == i2 evaluates to true and for other values i1 == i2 evaluates to false.

What could be the reason behind this behaviour?

Thank You,
Sanket Meghani.
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Advanced question? Not really.

First thing to say is that one should not be comparing Integer objects with == and expecting it to tell you whether they have equal numeric values. Use equals() for that.

When you use autoboxing to wrap int constants in Integer objects, you normally get a new Integer object. Thus, two autoboxings of the same value get different Integer objects, and == gives false (but equals() gives true, of course).

The JVM (or is it the compiler, I dunno) may use canonical cached objects for small values. That saves it from repeatedly creating new Integer objects for common values like -1, 0, 1, 2 etc. When this happens, two autoboxings of the same numeric value actually get the same object, so == tests true.

I think this is an internal implementation detail of a JVM, and I hope it is not standardised. Certainly, anyone who wrote a program that depended on this should be forced to write Perl, or whacked in the head (which would render them ideal for Perl programming...).
[ August 03, 2007: Message edited by: Peter Chase ]

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

OUch, and then Peter told us what he really thought of Perl programmers
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

Oh, and coming back to the original question, since I got distracted: as Peter said, the unexpected behaviour is in the first example, not the second, and you should always be using .equals() regardless.
Also note that in practice you won't know the value of the variable (otherwise why make it variable?) and therefore you wouldn't be counting on the behaviour seen anyway.
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Originally posted by David O'Meara:
OUch, and then Peter told us what he really thought of Perl programmers


Or substitute the brain-damaged language (other than Java, of course) of your choice.
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3527
    
  15
Originally posted by Peter Chase:

I think this is an internal implementation detail of a JVM, and I hope it is not standardised.


I'm afraid it is. See Section 5.1.7 of the JLS.


Joanne
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41800
    
  62
Autoboxing an int to an Integer happens using the Integer.valueOf method, which does cache a limited range of Integer objects.

If the code had been

then two different objects would have been created, regardless of the argument.


Ping & DNS - my free Android networking tools app
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Originally posted by Joanne Neal:
I'm afraid it is. See Section 5.1.7 of the JLS.


Oh dear. Well, people still shouldn't depend on it, IMHO.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I would say it's partly specified in the JLS. That is, the JLS does specify that for all int values in the range -128 to 127, identical values must autobox to the same wrapper. However they do not specify exactly what happens outside this range. It would be perfectly legal for a particular JDK implementation to cache a larger range of wrapper values. So while you could depend on the fact that i1 == i2 when both are set to 100, you should not depend on the fact that i1 != i2 when both are set to 1000. It may be true for most (perhaps all) current JDKs, but it need not be true always.

Note that in current JDK implementations, Long wrappers are cached in the range -128 to 127, even though the JLS does not require this. So there is one example where the JDK exceeds the requirements of the JLS. Others may or may not occur in the future.

Overall though I would agree with Peter that even if some aspects of this behavior are guaranteed, it's probably a bad idea for programmers to rely on it. If only because this is the sort of trivia that's hard for programmers to remember, and other people reading your code may not be aware of it. Better to just avoid using == at all, where object wrappers are concerned.


"I'm not back." - Bill Harding, Twister
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Strange Behaviour Of Wrapper Class