Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why equal operator works for Integer value until 128 number? [duplicate]

Why Integer == operator does not work for 128 and after Integer values? Can someone explain this situation?

This is my Java environment:

java version "1.6.0_37" Java(TM) SE Runtime Environment (build 1.6.0_37-b06) Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01, mixed mode) 

Sample Code:

Integer a; Integer b; a = 129; b = 129;  for (int i = 0; i < 200; i++) {     a = i;     b = i;      if (a != b) {         System.out.println("Value:" + i + " - Different values");     } else {         System.out.println("Value:" + i + " - Same values");     } } 

Some part of console output:

Value:124 - Same values Value:125 - Same values Value:126 - Same values Value:127 - Same values Value:128 - Different values Value:129 - Different values Value:130 - Different values Value:131 - Different values Value:132 - Different values 
like image 843
gokhansari Avatar asked Feb 22 '13 13:02

gokhansari


People also ask

Why operator works for Integer value until 127?

Because int values from -127 to 127 are in a range which most JVM will like to cache so the VM actually uses the same object instance (and therefore memory address) for both i1 and i2. As a result, == returns a true result.

Why is 128 == 128 false but 127 == 127 is true when comparing Integer wrappers in Java?

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. If you pass the number beyond this range, then only it creates a new Integer object.

Can equals be used .equals for Integer?

We can use the equals() method to compare two integers in Java. It returns true if both objects are equal; otherwise, it returns false.


2 Answers

Check out the source code of Integer . You can see the caching of values there.

The caching happens only if you use Integer.valueOf(int), not if you use new Integer(int). The autoboxing used by you uses Integer.valueOf.

According to the JLS, you can always count on the fact that for values between -128 and 127, you get the identical Integer objects after autoboxing, and on some implementations you might get identical objects even for higher values.

Actually in Java 7 (and I think in newer versions of Java 6), the implementation of the IntegerCache class has changed, and the upper bound is no longer hardcoded, but it is configurable via the property "java.lang.Integer.IntegerCache.high", so if you run your program with the VM parameter -Djava.lang.Integer.IntegerCache.high=1000, you get "Same values" for all values.

But the JLS still guarantees it only until 127:

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly.

For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all characters and shorts, as well as integers and longs in the range of -32K - +32K.

like image 187
lbalazscs Avatar answered Oct 23 '22 05:10

lbalazscs


Integer is a wrapper class for int.

Integer != Integer compares the actual object reference, where int != int will compare the values.

As already stated, values -128 to 127 are cached, so the same objects are returned for those.

If outside that range, separate objects will be created so the reference will be different.

To fix it:

  • Make the types int or
  • Cast the types to int or
  • Use .equals()
like image 27
Bernhard Barker Avatar answered Oct 23 '22 04:10

Bernhard Barker