consider the following program:
public class Test {
public static void main(String args[]) {
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a == b);
}
}
The output of this program is false
. for float and integer types java has primitive types (int
, long
, float
, double
, ...) which are not objects, and the object counterparts (Integer
, Long
, Float
, Double
, ...), which are objects. When we write
int a = 3;
int b = 3;
The value 3
is assigned to two variables a
and b
of primitive types. the two variables can be tested for equality with ==
, which in this example will return true
.
But if you write this:
Integer a = 3;
Integer b = 3;
Thanks to a feature called autoboxing, this is actually syntactic sugar for:
Integer a = new Integer(3);
Integer b = new Integer(3);
here we have two variables, each one referencing an object of class Integer
. The two instances of Integer
are distinct, even though semantically they reflect the same underlying int value. In java the ==
operator applied to variables referencing objects tests whether the two variable are identical, i.e. if they reference the same object instance. Hence
Integer a = 3;
Integer b = 3;
System.out.println(a == b);
will print false
, as the two integer created by the autoboxing are distinct. On the other side, this:
Integer a = 3;
Integer b = a;
System.out.println(a == b);
will print true
, as b
refers the same object created by autoboxing when a
is declared.
In addition to testing for identity, for non-primitive variables you can test for equality using the equals()
method. So this:
Integer a = 3;
Integer b = 3;
System.out.println(a.equals(b));
will print true
. the equals()
method is defined in the Object
class, hence any class inherits. The one defined in Object
checks for identity, but each subclass should override the method to provide the expected semantic. In the case of Integer
for example, the redefinition checks the identity of the primitive member variable holding the integer value.