Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The following code prints "true, true, false, true". Shouldn't it be "true, true, true, true"?

Tags:

java

Integer i = 127;
Integer j = 127;
System.out.println(i == j);
System.out.println(i.equals(j));

Integer i1 = 128;
Integer j1 = 128;
System.out.println(i1 == j1);
System.out.println(i1.equals(j1));

I don't understand why its not print "true, true, true, true". please give answer?

like image 565
Sanjeev Avatar asked Mar 23 '10 12:03

Sanjeev


4 Answers

When you use ==, you're comparing the object instances for equality.

The reason that the first two instances are equal is that you created the Integers by using autoboxing (rather than calling new Integer(127)), and the Java Language Specification §5.1.7 requires that Integers between -128 and 127 are cached.

Implementations can cache more values than that but are not required to; apparently the JVM you are using does not cache 128. This is the case for Sun Java 6.

like image 163
Michael Myers Avatar answered Oct 20 '22 19:10

Michael Myers


just to add to all the other correct answers, take a look at the source code in order to fully understand what @mmyers is saying:

  584       /**
  585        * Returns an {@code Integer} instance representing the specified
  586        * {@code int} value.  If a new {@code Integer} instance is not
  587        * required, this method should generally be used in preference to
  588        * the constructor {@link #Integer(int)}, as this method is likely
  589        * to yield significantly better space and time performance by
  590        * caching frequently requested values.
  591        *
  592        * @param  i an {@code int} value.
  593        * @return an {@code Integer} instance representing {@code i}.
  594        * @since  1.5
  595        */
  596       public static Integer valueOf(int i) {
  597           final int offset = 128;
  598           if (i >= -128 && i <= 127) { // must cache
  599               return IntegerCache.cache[i + offset];
  600           }
  601           return new Integer(i);
  602       }
like image 37
Tom Avatar answered Oct 20 '22 21:10

Tom


Integer is a class. If you type new Integer() you create a new object. So i, j, i1 and j1 are all different objects. If you use == it's only true on the same object. For Integers smaller than 128 the JVM is using always the same object, so that outputs true.

like image 35
Mnementh Avatar answered Oct 20 '22 21:10

Mnementh


No it shouldn't:

Integer i1 = 128;
Integer j1 = 128;

Autoboxing causes two distinct Integer objects to be created in the implementation of Java that you are using.

If the integer values were in the range -128 to 127, then the JLS states that the same Integer object would be used; see JLS 1.5.7. However, the JLS does not require that i1 and i2 must have different values outside of that range. Indeed the following discussion in the JLS says this:

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 35
Stephen C Avatar answered Oct 20 '22 20:10

Stephen C