Types and Type-checking in JavaTopPre-Defined Data types in JavaEquality in Java

Equality in Java

Java has two main equality operations, the operator == and the method equals. Because you cannot send method requests to primitive values, you must use == to compare them. It is more complicated with object types, however. The operator == on object types has a fixed meaning corresponding to object identity, while the equals method can be overridden in a class and is typically defined to mean the two objects have the same value. This is a bit subtle, so let's look at an example.

Suppose p and q are variables holding locations, constructed as follows:

   Location p = new Location(1,3)
   Location q = new Location(1,3)

then p == q is false, because they are different objects, even though they have the same x and y components. However, p.equals(q) will be true, because we defined the equals method in class Location to return true whenever the two objects have the same x and y values.

On the other hand, if we define another variable r and initialize it with p:

   Location r = p

then r == p, because r and p both refer to the same object. Of course, we also have r.equals(p) because logically they are the same. In general if x == y, where x and y refer to objects, then we will also have x.equals(y). However the reverse is NOT true.

For example, suppose we have the following Java code:

   String a = "hello";
   String b = "he";
   String c = "llo";
   System.out.println (a==(b+c));
   System.out.println (a.equals(b+c));

When executed the first print will show false and the second true. Confusingly, however, the Java compiler tries very hard to statically determine the values of strings, and then rather than have multiple copies, have them shared rather than making separate copies. This is generally fine because strings are immutable. However it means that the results of == are sometimes surprising. For example, if we execute the following:

   String a = "hello";
   String b = "he"+"llo";
   System.out.println (a==b);
   System.out.println (a.equals(b));

then the system will print out true for each. That is because the compiler is smart enough to realize that the two initial values are the same, but in the previous example, it was not quite smart enough to realize that b+c was the same as a.

The bottom line is that almost always the correct comparison operator for objects is the method equals, and when you define a new class, always define equals to mean the "right" thing. It is especially important that when you compare strings you NEVER use ==, but instead use equals.


Types and Type-checking in JavaTopPre-Defined Data types in JavaEquality in Java