Copyi1 == i2
results in un-boxing and a regular int comparison is done. (see first point in JLS 5.6.2)
Copyi2 == i3
results in reference comparsion. Remember, i2 and i3 are two different objects. (see JLS 15.21.3)
Copyi1 == i2
results in un-boxing and a regular int comparison is done. (see first point in JLS 5.6.2)
Copyi2 == i3
results in reference comparsion. Remember, i2 and i3 are two different objects. (see JLS 15.21.3)
CopyInteger i2 = 1;
This results is autoboxing. You are converting int(primitive type) to it's corresponding wrapper.
Copy Integer i3 = new Integer(1);
Here no need of autoboxing as you are directly creating an Integer object.
Now in
Copyi1 == i2
i1 == i3
i2 and i3 are automatically unboxed and regular int comparison takes place which is why you get true.
Now consider
Copyi2 == i3
Here both i2 and i3 are Integer objects that you are comparing. Since both are different object(since you have used new operator) it will obviously give false. Note == operator checks if two references point to same object or not. Infact .equals() method if not overridden does the same thing.
It is same as saying
Copy Integer i2 = new Integer(1);
Integer i3 = new Integer(1);
System.out.println("i2 == i3 "+(i2==i3));
which will again give you false.
I only found out about the .compare method when I let Intellij overwrite the equals method.
Can these be used interchageably?
Videos
No, == between Integer, Long etc will check for reference equality - i.e.
Integer x = ...;
Integer y = ...;
System.out.println(x == y);
this will check whether x and y refer to the same object rather than equal objects.
So
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y);
is guaranteed to print false. Interning of "small" autoboxed values can lead to tricky results:
Integer x = 10;
Integer y = 10;
System.out.println(x == y);
This will print true, due to the rules of boxing (JLS section 5.1.7). It's still reference equality being used, but the references genuinely are equal.
If the value p being boxed is an integer literal of type int between -128 and 127 inclusive (ยง3.10.1), or the boolean literal true or false (ยง3.10.3), or a character literal between '\u0000' and '\u007f' inclusive (ยง3.10.4), then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.
Personally I'd use:
if (x.intValue() == y.intValue())
or
if (x.equals(y))
As you say, for any comparison between a wrapper type (Integer, Long etc) and a numeric type (int, long etc) the wrapper type value is unboxed and the test is applied to the primitive values involved.
This occurs as part of binary numeric promotion (JLS section 5.6.2). Look at each individual operator's documentation to see whether it's applied. For example, from the docs for == and != (JLS 15.21.1):
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).
and for <, <=, > and >= (JLS 15.20.1)
The type of each of the operands of a numerical comparison operator must be a type that is convertible (ยง5.1.8) to a primitive numeric type, or a compile-time error occurs. Binary numeric promotion is performed on the operands (ยง5.6.2). If the promoted type of the operands is int or long, then signed integer comparison is performed; if this promoted type is float or double, then floating-point comparison is performed.
Note how none of this is considered as part of the situation where neither type is a numeric type.
Since Java 1.7 you can use Objects.equals:
java.util.Objects.equals(oneInteger, anotherInteger);
Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument.