8.2 The Object Class
All classes extend the Object class, either directly or indirectly. A class declaration, without the extends clause, implicitly extends the Object class (§5.1, p. 191). Thus the Object class is always at the root of any inheritance hierarchy. The Object class defines the basic functionality that all objects exhibit and all classes inherit. This relationship also applies to arrays, since these are genuine objects in Java.
The Object class defines common functionality for all objects through the following methods (see Example 8.1 for usage of these methods):
public boolean equals(Object obj)
The general contract of the equals() method is discussed in connection with object comparison (§14.2, p. 744). Object reference and value equality are discussed together with the == and != operators (§2.13, p. 75). The equals() method in the Object class returns true only if the two references compared denote the same object—that is, they are aliases. The equals() method is normally overridden to provide the semantics of object value equality, as is the case for the wrapper classes (p. 432) and the String class (p. 439).
public int hashCode()
Returns an int value as the hash value of the object. The general contract of the hashCode() method is discussed in connection with object comparison (§14.3, p. 753). In hash tables, the hash value can be used to store and retrieve objects efficiently (§15.8, p. 830). The hashCode() method is normally overridden by a class, as is the case for the wrapper classes (p. 432) and the String class (p. 439).
public String toString()
The general contract of the method is to return a text representation of the object. If a subclass does not override this method, it returns a text representation of the object, which has the following format:
“
<class_name>
@
<hash_code>
“
Since the hash value of an object is an int value, this value is printed as a hexadecimal number (e.g., 3e25a5). This method is usually overridden by a class to provide appropriate text representation for its object. The method call System.out.println(objRef) will implicitly convert its argument to a text representation by calling the toString() method on the argument.
public final Class<?> getClass()
Returns the runtime class of the object, which is represented by an object of the class java.lang.Class at runtime.
protected Object clone() throws CloneNotSupportedException
New objects that are exactly the same (i.e., have identical states) as the current object can be created by using the clone() method; that is, primitive values and reference values are copied. This is called shallow copying. A class can override this method to provide its own notion of cloning. For example, cloning a composite object by recursively cloning the constituent objects is called deep copying.
When overridden, the method in the subclass is usually declared as public to allow any client to clone objects of the class. Not declaring the overriding method as public or protected violates the contract for overriding, as it narrows the accessibility of the method, and will be flagged as a compile-time error.
If the overriding clone() method in the subclass relies on the clone() method in the Object class (i.e., a shallow copy), the subclass must implement the Cloneable marker interface to indicate that its objects can be safely cloned. Otherwise, the clone() method in the Object class will throw a checked CloneNotSupported-Exception.
@Deprecated(since=”9″) protected void finalize() throws Throwable
This method is called on an object just before it is garbage collected so that any clean-up can be done. However, the finalize() method in the Object class has been deprecated since Java 9—it should no longer be used and it may be removed in the future. The method is deemed problematic, and better solutions exist for implementing the same functionality.
In addition, the following final methods in the Object class provide support for thread communication in synchronized code (§22.4, p. 1400).
public final void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
public final void wait() throws InterruptedException
public final void notify()
public final void notifyAll()
A thread invokes these methods on the object whose lock it holds. A thread waits for notification by another thread.
Example 8.1 Methods in the Object Class
// File: ObjectMethods.java
class MyClass implements Cloneable {
@Override
public MyClass clone() {
MyClass obj = null;
try { obj = (MyClass) super.clone(); } // Calls overridden method.
catch (CloneNotSupportedException e) { System.out.println(e);}
return obj;
}
}
//______________________________________________________________________________
public class ObjectMethods {
public static void main(String[] args) {
// Two objects of MyClass.
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
// Two strings.
String str1 = new String(“WhoAmI”);
String str2 = new String(“WhoAmI”);
System.out.println(“str1: ” + str1.toString());
System.out.println(“str2: ” + str2.toString() + “\n”);
// Method hashCode() overridden in String class.
// Strings that are equal have the same hash code.
System.out.println(“hash code for str1: ” + str1.hashCode());
System.out.println(“hash code for str2: ” + str2.hashCode() + “\n”);
// Hash codes are different for different MyClass objects.
System.out.println(“hash code for MyClass obj1: ” + obj1.hashCode());
System.out.println(“hash code for MyClass obj2: ” + obj2.hashCode()+”\n”);
// Method equals() overridden in the String class.
System.out.println(“str1.equals(str2): ” + str1.equals(str2));
System.out.println(“str1 == str2: ” + (str1 == str2) + “\n”);
// Method equals() from the Object class called.
System.out.println(“obj1.equals(obj2): ” + obj1.equals(obj2));
System.out.println(“obj1 == obj2: ” + (obj1 == obj2) + “\n”);
// The runtime object that represents the class of an object.
Class<? extends String> rtStringClass = str1.getClass();
Class<? extends MyClass> rtMyClassClass = obj1.getClass();
// The name of the class represented by the runtime object.
System.out.println(“Class for str1: ” + rtStringClass);
System.out.println(“Class for obj1: ” + rtMyClassClass + “\n”);
// The toString() method is overridden in the String class.
String textRepStr = str1.toString();
String textRepObj = obj1.toString();
System.out.println(“Text representation of str1: ” + textRepStr);
System.out.println(“Text representation of obj1: ” + textRepObj + “\n”);
// Shallow copying of arrays.
MyClass[] array1 = {new MyClass(), new MyClass(), new MyClass()};
MyClass[] array2 = array1.clone();
// Array objects are different, but share the element objects.
System.out.println(“array1 == array2: ” + (array1 == array2));
for(int i = 0; i < array1.length; i++) {
System.out.println(“array1[” + i + “] == array2[” + i + “] : ” +
(array1[i] == array2[i]));
}
System.out.println();
// Clone an object of MyClass.
MyClass obj3 = obj1.clone();
System.out.println(“hash code for cloned MyClass obj3: ” + obj3.hashCode());
System.out.println(“obj1 == obj3: ” + (obj1 == obj3));
}
}
Probable output from the program:
str1: WhoAmI
str2: WhoAmI
hash code for str1: -1704812257
hash code for str2: -1704812257
hash code for MyClass obj1: 2036368507
hash code for MyClass obj2: 1785210046
str1.equals(str2): true
str1 == str2: false
obj1.equals(obj2): false
obj1 == obj2: false
Class for str1: class java.lang.String
Class for obj1: class MyClass
Text representation of str1: WhoAmI
Text representation of obj1: MyClass@7960847b
array1 == array2: false
array1[0] == array2[0] : true
array1[1] == array2[1] : true
array1[2] == array2[2] : true
hash code for cloned MyClass obj3: 1552787810
obj1 == obj3: false
Leave a Reply