Comparing Object Values and Classes
In addition to casting, there are three other common tasks you will often perform that involve objects:
Comparing objects
Finding out the class of any given object
Testing to see whether an object is an instance of a given class
Comparing Objects
Yesterday you learned about operators for comparing valuesequal, not equal, less than, and so on. Most of these operators work only on primitive types, not on objects. If you try to use other values as operands, the Java compiler produces errors.
The exceptions to this rule are the operators for equality: == (equal) and != (not equal). When applied to objects, these operators don't do what you might first expect. Instead of checking whether one object has the same value as the other object, they determine whether both sides of the operator refer to the same object.
To compare instances of a class and have meaningful results, you must implement special methods in your class and call those methods.
A good example of this is the String class. It is possible to have two different String objects that contain the same values. If you were to employ the == operator to compare these objects, however, they would be considered unequal. Although their contents match, they are not the same object.
To see whether two String objects have matching values, a method of the class called equals() is used. The method tests each character in the string and returns true if the two strings have the same values. Listing 3.5 illustrates this.
Listing 3.5 The Full Text of EqualsTest.java
1: class EqualsTest { 2: public static void main(String[] arguments) { 3: String str1, str2; 4: str1 = "Free the bound periodicals."; 5: str2 = str1; 6: 7: System.out.println("String1: " + str1); 8: System.out.println("String2: " + str2); 9: System.out.println("Same object? " + (str1 == str2)); 10: 11: str2 = new String(str1); 12: 13: System.out.println("String1: " + str1); 14: System.out.println("String2: " + str2); 15: System.out.println("Same object? " + (str1 == str2)); 16: System.out.println("Same value? " + str1.equals(str2)); 17: } 18: }
This program's output is as follows:
String1: Free the bound periodicals. String2: Free the bound periodicals. Same object? true String1: Free the bound periodicals. String2: Free the bound periodicals. Same object? false Same value? true
The first part of this program (lines 35) declares two variables (str1 and str2), assigns the literal Free the bound periodicals. to str1, and then assigns that value to str2. As you learned earlier, str1 and str2 now point to the same object, and the equality test at line 9 proves that.
In the second part of this program, you create a new String object with the same value as str1 and assign str2 to that new String object. Now you have two different string objects in str1 and str2, both with the same value. Testing them to see whether they're the same object by using the == operator (line 15) returns the expected answer: falsethey are not the same object in memory. Testing them using the equals() method in line 16 also returns the expected answer: truethey have the same values.
NOTE
Why can't you just use another literal when you change str2, rather than using new? String literals are optimized in Java; if you create a string using a literal and then use another literal with the same characters, Java knows enough to give you the first String object back. Both strings are the same objects; you have to go out of your way to create two separate objects.
Determining the Class of an Object
Want to find out what an object's class is? Here's the way to do it for an object assigned to the variable key:
String name = key.getClass().getName();
What does this do? The getClass() method is defined in the Object class and is therefore available for all objects. The result of that method is a Class object (where Class is itself a class) that has a method called getName(). In turn, getName() returns a string representing the name of the class.
Another test that might be useful is the instanceof operator. instanceof has two operands: a reference to an object on the left and a class name on the right. The expression returns true or false based on whether the object is an instance of the named class or any of that class's subclasses:
boolean ex1 = "Texas" instanceof String; // true Object pt = new Point(10, 10); boolean ex2 = pt instanceof String; // false
The instanceof operator can also be used for interfaces. If an object implements an interface, the instanceof operator with that interface name on the right side returns true.