user89749
user89749

Reputation: 301

JDK Issue with Integer Comparision

In jdk 1.6.0_24 comparison of two Integer Objects with same int value is failing?

Issue :

Integer x = 2;
Integer y = 2;

If(x != y){
 //Control should not come here, but controls come here . In jdk 1.6.0_26 it is working.
}

Changing code snippet as below works fine then.

Integer x = 2;
Integer y = 2;

If(x.intValue() != y.intValue()){
 //works fine.
}

Any answer ? Is it jdk bug?

Thanks in advance. Bhupendra Kalakoti

Upvotes: 1

Views: 565

Answers (5)

Martyn Davis
Martyn Davis

Reputation: 624

I just had to prove this - seeing is believing so they say:

public class test
{
    public static void main(String[] args) throws Exception 
    {
        final Integer intValue2 = 2;
        Integer intValue = Integer.valueOf("2");

        System.out.println("INFO: intValue2 = " + intValue2);
        System.out.println("INFO: intValue  = " + intValue);
        if (intValue2 == intValue)
            System.out.println("PASS: Values are equal");
        else
            System.out.println("FAIL: Values are not equal");
    }
}

Using Java 1.6.0_7:

INFO: intValue2 = 2
INFO: intValue  = 2
FAIL: Values are not equal

Using Java 1.6.0_18:

INFO: intValue2 = 2
INFO: intValue  = 2
PASS: Values are equal

Whereas, using a non "small" value, such as 123456789, this will fail irrespective of Java version:

Using Java 1.6.0_7:

INFO: intValue2 = 1234567890
INFO: intValue  = 1234567890
FAIL: Values are not equal

Using Java 1.6.0_18:

INFO: intValue2 = 1234567890
INFO: intValue  = 1234567890
FAIL: Values are not equal

Upvotes: 0

pyroscope
pyroscope

Reputation: 4158

As Mario already hinted, you fall prey here to a pure optimization of the JVM. Small integers (with "small" being a fuzzy definition, depending on JVM version and settings) are cached, so they don't need to be constantly created (under the assumption small numbers are used very often).

JVM vendors change what optimizations they apply by default constantly, so that explains why you experience the difference when changing versions.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533580

When you use == with objects you are comparing references i.e. are they the same object. However when you use == with primitives, you are comparing their values.

In your case, you are using objects which have been autoboxed. For Integer, the Integer.valueOf() method is called and it caches small values between -128 and 127 (the default maximum) and has done so since 2004 when Java 5.0 was released.

BTW: You can increase the size of the Integer cache with

  • -Djava.lang.Integer.IntegerCache.high=value
  • -XX:AutoBoxCacheMax=value
  • -XX:+AggressiveOpts

http://www.javaspecialists.eu/archive/Issue191.html

Upvotes: 0

nobody
nobody

Reputation: 1949

Integer is an Object where as int is primitive. To compare objects you shuld be using .equals method. == or != checks whether they are in same address in heap which may or may not be TRUE because of the caching JVM applies to Strings and objects like this.

.intValue() comparison goes fine because you are comparing primitive value of those objects.

Upvotes: 0

SJuan76
SJuan76

Reputation: 24885

One of the best and funniest posts I found here: Strangest language feature

Check the "Fun with auto boxing and the integer cache in Java" (about 498 votes) answer.

Upvotes: 1

Related Questions