participate


Java Programming - Confused about "==" to compare Integer wrapper objects
<<   Back to Forum  |   Give us Feedback
This topic has 17 replies on 2 pages.    1 | 2 | Next »
lapchern
Posts:34
Registered: 6/2/01
Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 6:30 PM

 
I'm studying for SCJP 6 and am going over the autoboxing section..

Here's an excerpt of the guide:

In order to save memory, two instances of the following wrapper objects (created through boxing), will always be == when their primitive values are the same:

Boolean

Byte

Character from \u0000 to \u007f (7f is 127 in decimal)

Short and Integer from -128 to 127
Note: When == is used to compare a primitive to a wrapper, the wrapper will be unwrapped and the comparison will be primitive to primitive.

In the code below, I try to test this. I expect all 4 reference variables to be "equal" based on the description of how "==" supposedly behaves. Can someone clarify why they are not "equal?"

class TestNum {
 
	public static void main(String[] args) {
		Integer i3 = new Integer(100);
		Integer i4 = new Integer(100);
		System.out.println("Value of i3 is : "+i3.intValue());
		System.out.println("Value of i4 is : "+i4.intValue());
 
 
		Integer i5 = 100;
		Integer i6 = 100;
		System.out.println("Value of i5 is : "+i5.intValue());
		System.out.println("Value of i6 is : "+i6.intValue());
 
		if(i3==i4)
			System.out.println("i3==i4");
 
		if(i4==i5)
			System.out.println("i4==i5");
 
		if(i5==i6)
			System.out.println("i5==i6");
 
 
 
	}
}


Output:

Value of i3 is : 100
Value of i4 is : 100
Value of i5 is : 100
Value of i6 is : 100
i5==i6

Edited by: lapchern on Nov 7, 2009 6:30 PM
 
jverd
Posts:51,828
Registered: 3/30/99
Re: Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 6:33 PM (reply 1 of 17)  (In reply to original post )

 
two instances of the following wrapper objects (created through boxing)
 
lapchern
Posts:34
Registered: 6/2/01
Re: Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 6:41 PM (reply 2 of 17)  (In reply to #1 )

 
ah sorry... that just slipped past my head. does anyone know if this means that java preloads some sort of Integer objects (from -128 to 127) into memory?

for example:

Integer i5 = 100;
Integer i6 = 100;

The 100 value already has an object reserved for it for i5 and i6 to point to?

thanks
 
jverd
Posts:51,828
Registered: 3/30/99
Re: Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 6:45 PM (reply 3 of 17)  (In reply to #2 )

 
lapchern wrote:
ah sorry... that just slipped past my head. does anyone know if this means that java preloads some sort of Integer objects (from -128 to 127) into memory?

Yes, I believe those are preloaded, though it's really irrelevant. The JLS and/or JVM spec will have the answer if you're really interested.
 
lapchern
Posts:34
Registered: 6/2/01
Re: Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 6:48 PM (reply 4 of 17)  (In reply to #3 )

 
yeah it's irrelevant... just one of those things that bugs me that keeps me from moving along :-). thanks again for your help, jverd.
 
heri2000
Posts:9
Registered: 1/28/09
Re: Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 7:41 PM (reply 5 of 17)  (In reply to original post )

 
Add these lines after those three "if"s...
	System.out.println("i3 hash code: " + System.identityHashCode(i3));
	System.out.println("i4 hash code: " + System.identityHashCode(i4));
	System.out.println("i5 hash code: " + System.identityHashCode(i5));
	System.out.println("i6 hash code: " + System.identityHashCode(i6));

Run it to get the output. On my machine, I got
Value of i3 is : 100
Value of i4 is : 100
Value of i5 is : 100
Value of i6 is : 100
i5==i6
i3 hash code: 4072869
i4 hash code: 1671711
i5 hash code: 11394033
i6 hash code: 11394033

the first two tests return false because they are not the same objects (they have different hash codes).
If you want to test the values are equal or not, you can unbox the Integer to get their primitive values using intValue().
	if (i3.intValue() == i4.intValue()) {
	    System.out.println("i3==i4");
	}
	if (i4.intValue() == i5.intValue()) {
	    System.out.println("i4==i5");
	}
	if (i5.intValue() == i6.intValue()) {
	    System.out.println("i5==i6");
	}

the other way, use if (i3.equals(i4)) etc.
 
jverd
Posts:51,828
Registered: 3/30/99
Re: Confused about "==" to compare Integer wrapper objects   
Nov 7, 2009 7:49 PM (reply 6 of 17)  (In reply to #5 )

 
heri2000 wrote:
the first two tests return false because they are not the same objects (they have different hash codes).

You don't need hashcode to know if two references point to the same object. Simply using == will do. And == has the added benefit that if it's true, they must be the same object, whereas with hashCode, you can get two different objects with the same hashCode.
 
Peter__Lawrey
Posts:4,383
Registered: 7/30/03
Re: Confused about "==" to compare Integer wrapper objects   
Nov 8, 2009 12:10 AM (reply 7 of 17)  (In reply to original post )

 
Have a look at the code for Integer.valueof(int) which is called for auto-boxing. Since Java 6u14 the size of the cache of the Integer cache is configurable.

Note: Long also has a cache.

private static class IntegerCache {
        static final int high;
        static final Integer cache[];
 
        static {
            final int low = -128;
 
            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;
 
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }
 
        private IntegerCache() {}
    }
 
    /**
     * Returns a <tt>Integer</tt> instance representing the specified
     * <tt>int</tt> value.
     * If a new <tt>Integer</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Integer(int)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  i an <code>int</code> value.
     * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }
 
YoungWinston
Posts:1,220
Registered: 2/19/07
Re: Confused about "==" to compare Integer wrapper objects   
Nov 9, 2009 3:41 AM (reply 8 of 17)  (In reply to original post )

 
lapchern wrote:
I'm studying for SCJP 6 and am going over the autoboxing section...
I sympathize; and apart from the other excellent advice given above, I can only offer this: try not to rely on it.

In general, you're far better off with 'equals()' than '==', (witness the number of questions on this forum by people who write 'string1 == string2' and can't understand why their program doesn't work), and the compiler will soon let you know when you use it inappropriately.

With a few exceptions, explicit boxing and unboxing can make your code easier for other people to read and understand, especially in cases where widening and method choice are also involved. It also provides evidence that you aren't just "being lazy".
That said, it (auto[un]boxing) does generally work the way you'd hope.

Remember: the SCJP exam is designed to test your grasp of concepts, not to provide real-life examples.

Winston
 
endasil
Posts:2,762
Registered: 10/12/07
Re: Confused about "==" to compare Integer wrapper objects   
Nov 9, 2009 6:21 AM (reply 9 of 17)  (In reply to #8 )

 
YoungWinston wrote:
Remember: the SCJP exam is designed to test your grasp of concepts
If only that were true...

I would change that to
Remember: the SCJP exam is designed to test nuances of the language that, if they actually arose in your real job, would be a good indication that you should quit.
 
YoungWinston
Posts:1,220
Registered: 2/19/07
Re: Confused about "==" to compare Integer wrapper objects   
Nov 10, 2009 7:27 AM (reply 10 of 17)  (In reply to #9 )

 
endasil wrote:
I would change that to
Remember: the SCJP exam is designed to test nuances of the language that, if they actually arose in your real job, would be a good indication that you should quit.
I hope you don't mind if I quote you :-).

Winston
 
endasil
Posts:2,762
Registered: 10/12/07
Re: Confused about "==" to compare Integer wrapper objects   
Nov 10, 2009 7:48 AM (reply 11 of 17)  (In reply to #10 )

 
YoungWinston wrote:
endasil wrote:
I would change that to
Remember: the SCJP exam is designed to test nuances of the language that, if they actually arose in your real job, would be a good indication that you should quit.
I hope you don't mind if I quote you :-).
Sure. By the way, at this thread a link was given to this article (which looks promising!). Here's what one of the readers ("Matt") had to say about the SCJP:

Whatever the case, something should be done. The current exams, to simplify the explanation, focus on having the test taker be able to act as a human compiler.

At least 50% [at Least] of the questions on the exams / practice exams I’ve seen and taken are questions that should never, ever be given time to solve in the work environment. (...SNIP...)

If any developer of mine tried to waste time solving for that instead of letting the compiler do it, I would need to discuss their time management strategy.

(...SNIP...) the exams themselves, they do not prove one way or the other whether someone can program — only whether they can compile if the power goes out.

I have to agree completely.
 
georgemc
Posts:16,804
Registered: 5/8/06
Re: Confused about "==" to compare Integer wrapper objects   
Nov 10, 2009 8:25 AM (reply 12 of 17)  (In reply to #11 )

 
I like how the first commenter on the article completely missed the point about API docs.

edit: or maybe it's just that his grammar makes it look that way.

Edited by: georgemc on Nov 10, 2009 4:24 PM
 
endasil
Posts:2,762
Registered: 10/12/07
Re: Confused about "==" to compare Integer wrapper objects   
Nov 10, 2009 8:33 AM (reply 13 of 17)  (In reply to #12 )

 
georgemc wrote:
I like how the first commenter on the article completely missed the point about API docs.

edit: or maybe it's just that his grammar makes it look that way.

Edited by: georgemc on Nov 10, 2009 4:24 PM
Yeah, I had to read that like 4 times to decide whether he was posing that as a question or agreeing with the opposite of what the author was arguing.

I don't think there's anything harmful about studying and memorizing the Java API. But it wouldn't hold any weight with me if I were trying to guage a person's programming ability. Knowing generally what it contains and then being able to use it as a reference is far more important to me. That way, if my company decides to switch/add a technology, I know that my staff will be able to pick it up easily as well.
 
georgemc
Posts:16,804
Registered: 5/8/06
Re: Confused about "==" to compare Integer wrapper objects   
Nov 10, 2009 9:08 AM (reply 14 of 17)  (In reply to #13 )

 
endasil wrote:
georgemc wrote:
I like how the first commenter on the article completely missed the point about API docs.

edit: or maybe it's just that his grammar makes it look that way.

Edited by: georgemc on Nov 10, 2009 4:24 PM
Yeah, I had to read that like 4 times to decide whether he was posing that as a question or agreeing with the opposite of what the author was arguing.

I don't think there's anything harmful about studying and memorizing the Java API. But it wouldn't hold any weight with me if I were trying to guage a person's programming ability. Knowing generally what it contains and then being able to use it as a reference is far more important to me. That way, if my company decides to switch/add a technology, I know that my staff will be able to pick it up easily as well.

Working out how a library you've never seen before, just by using auto-complete in your IDE, makes you far more productive than memorizing anything, and good unit-testing habits keep you from being bitten by surprises. The problem with just studying the APIs is, most of it doesn't actually sink in, whereas using APIs does. In a way, the idea that deep API knowledge indicates experience might have some truth to it. You know, for instance, about String.toLowerCase, not because you studied the API, but because you've used it enough times for it to be second nature. If I post the question "How do I convert uppercase to lowercase in teh jav?" in the forum, you don't go "Oh, now what does the API tell me?" you just instinctively know what the answer is, because you're familiar with the API, you've got experience in using it.

Then again, sometimes API docs are necessary. Quickly, without looking it up, or trying it out, or anything, tell me what the result of the following code is:

System.out.println(Integer.getInteger("150"));
 
This topic has 17 replies on 2 pages.    1 | 2 | Next »
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 55
  • Guests : 140

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums