Is it guaranteed that new Integer(i) == i in Java?

 ̄綄美尐妖づ 提交于 2019-12-17 06:13:24

问题


Consider the following snippet:

    int i = 99999999;
    byte b = 99;
    short s = 9999;
    Integer ii = Integer.valueOf(9); // should be within cache

    System.out.println(new Integer(i) == i); // "true"
    System.out.println(new Integer(b) == b); // "true"
    System.out.println(new Integer(s) == s); // "true"
    System.out.println(new Integer(ii) == ii); // "false"

It's obvious why the last line will ALWAYS prints "false": we're using == reference identity comparison, and a new object will NEVER be == to an already existing object.

The question is about the first 3 lines: are those comparisons guaranteed to be on the primitive int, with the Integer auto-unboxed? Are there cases where the primitive would be auto-boxed instead, and reference identity comparisons are performed? (which would all then be false!)


回答1:


Yes. JLS §5.6.2 specifies the rules for binary numeric promotion. In part:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed.

Binary numeric promotion applies for several numeric operators, including "the numerical equality operators == and !=."

JLS §15.21.1 (Numerical Equality Operators == and !=) specifies:

If the operands of an equality operator are both of numeric type, or one is of numeric type and the other is convertible (§5.1.8) to numeric type, binary numeric promotion is performed on the operands (§5.6.2).

In contrast, JLS §15.21.3 (Reference Equality Operators == and !=) provides:

If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality

This fits the common understanding of boxing and unboxing, that's it only done when there's a mismatch.




回答2:


I will first explain precisely when == is a reference equality, and precisely when it's a numerical equality. The conditions for reference equality is simpler, so it will be explained first.

JLS 15.21.3 Reference Equality Operators == and !=

If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality.

This explains the following:

System.out.println(new Integer(0) == new Integer(0)); // "false"

Both operands are Integer, which are reference types, and that's why the == is reference equality comparison, and two new objects will never be == to each other, so that's why it prints false.

For == to be numerical equality, at least one of the operand must be a numeric type; this is specified as follows:

JLS 15.21.1 Numerical Equality Operators == and !=

If the operands of an equality operator are both of numeric type, or one is of numeric type and the other is convertible to numeric type, binary numeric promotion is performed on the operands. If the promoted type of the operands is int or long, then an integer equality test is performed; if the promoted type is float ordouble`, then a floating-point equality test is performed.

Note that binary numeric promotion performs value set conversion and unboxing conversion.

Thus, consider the following:

System.out.println(new Integer(0) == 0); // "true"

This prints true, because:

  • the right operand is a numeric int type
  • the left operand is convertible to a numeric type, by unboxing to int
  • therefore == is a numerical equality operation

Summary

  • If both operands of == and != are reference types, it will always be a reference equality operation
    • It doesn't matter if the operands are convertible to numeric types
  • If at least one of the operand is a numeric type, it will always be a numerical equality operation
    • Auto-unboxing on one (at most!) of the operands will be performed if necessary

References

  • JLS 4.2. Primitive Types and Values
    • "The numeric types are the integral types and the floating-point types."
  • Java Language Guide/Autoboxing
  • JLS 5.1.8 Unboxing Conversion
  • JLS 15.21.1 Numerical Equality Operators == and !=
  • JLS 15.21.3 Reference Equality Operators == and !=
  • JLS 5.6.2 Binary Numeric Promotion

Related questions

  • When comparing two Integers in Java does auto-unboxing occur?
  • Why are these == but not equals()?
  • Java: What’s the difference between autoboxing and casting?


来源:https://stackoverflow.com/questions/2831945/is-it-guaranteed-that-new-integeri-i-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!