Hello. Pass the test. Here, faced with incomprehensibility. Question:

What will be displayed on the screen?

Integer a = 128; Integer b = 128; Integer c = -128; Integer d = -128; System.out.println(a == b); System.out.println(c == d); 

I answered false, false . Wrong. Explanation:

To increase the boxing conversion efficiency (conversion of a primitive type value to an object of the corresponding wrapper class), pre-created objects of the Integer (-128 .. 127), Byte (-128 .. 127), Short (-128) classes are used for small integer values. .. 127), Character (0 .. 127). These sets are usually referred to as a cache (eg, integer cache) or a pool (eg, integer pool). Therefore, c == d gives true. For the remaining values, a new object is created each time during the boxing conversion. Therefore, a == b gives false.

And one more question:

 Integer ii = 1000; Integer jj = 2000; System.out.print((ii * 2 == jj) ? "yes " : "no "); System.out.print((jj / 2 == ii) ? "yes " : "no "); System.out.print((ii * 2 == jj) ^ (jj / 2 == ii) ? "yes " : "no "); 

I replied that there would be no no no . Wrong. Explanation:

When performing any arithmetic operations (multiplication, division, ...), the objects of the wrapper classes (Integer) are automatically expanded to values ​​of the primitive type (int). The result of any arithmetic operation will also be a value of a primitive type. If using == compares the value of the primitive type and the wrapper object, then the object automatically expands and the two primitives are compared. The result of the ^ (exclusive OR) operation will be false, since both operands are true.

Why the second question does not specify caching from -128 to 127? Thank.

  • What for? There are in fact no values ​​from -128 to 127. - default locale
  • 3
    The answer is already in the question. Read the explanations carefully. Both explanations. - D-side
  • one
    @ D-side, in an arithmetic operation, the shell unfolds into a primitive. And he no longer has caching, right?) - Flippy
  • one
    That's right! That is, it is impossible to say for sure that the shells of the arguments unfold (although surely inside), but the result is, in any case, primitive. - D-side

2 answers 2

If using == compares the value of the primitive type and the wrapper object, then the object automatically expands and the two primitives are compared.

You missed that moment. The cache for values ​​-128 - 127 is created for objects (that is, Integer, for int everything will be ok). And now:

When performing any arithmetic operations (multiplication, division, ...), the objects of the wrapper classes (Integer) are automatically expanded to values ​​of the primitive type

That is, when performing multiplication by 2, our Integer automatically turned into a normal int. And then we compare not the object, but the primitive with the object.

And then again we look at the first quote, when comparing with a primitive, the object also turns into a primitive (Integer -> int)

  • Understood thanks! It is interesting then, and if, for example, to add two Integer will they both turn into a primitive?) - Flippy
  • one
    Yes, turn around) new Integer(1000) + new Integer(1000) == new Integer(2000); // true new Integer(1000) + new Integer(1000) == new Integer(2000); // true . Frankly speaking, I don’t know why they ask about this on many Java tests, but still understand what Boxing is, unboxing, what a link is, and what a primitive it develops) - Uraty
  • thank you very much! - Flippy

A small clarification on the first part of the question: the upper limit of the cache for a particular Integer class can be increased by specifying it in the JVM java.lang.Integer.IntegerCache.high parameter. Thus a == b may be true .

But it is impossible to reduce, c == d will always be true .

Details of the details of the implementation of boxing can always be peeped in the code of the valueOf() method of the corresponding class (except for String , interning works there). A couple more examples can be found here .