Object Class
The root of every Java class: toString, equals, hashCode, clone, getClass, wait/notify and finalize.
#Introduction
In Java, every class directly or indirectly inherits from the Object class. It is the root (superclass) of the Java class hierarchy.
class Employee {
}The compiler internally treats it as:
class Employee extends Object {
}Even if you don't explicitly extend Object, Java does it automatically.
#Why Object Class?
The Object class provides common functionality that every Java object should have, such as:
- Comparing objects
- Generating hash codes
- Converting objects to strings
- Cloning objects
- Thread synchronization
- Runtime class information
Without Object, every class would need to implement these features separately.
#Object Class Hierarchy
- Object
- Employee
- Student
- Animal
#Methods of Object Class
The most commonly used methods are:
| Method | Purpose |
|---|---|
toString() | String representation of an object |
equals() | Compare object equality |
hashCode() | Generate hash value |
clone() | Create object copy |
getClass() | Return runtime class |
wait() | Put thread into waiting state |
notify() | Wake one waiting thread |
notifyAll() | Wake all waiting threads |
finalize() (Deprecated) | Cleanup before GC |
#1. toString()
Definition
Returns the string representation of an object. Default behaviour:
Object obj = new Object();
System.out.println(obj);java.lang.Object@5e2de80cInternally, System.out.println(obj); becomes System.out.println(obj.toString());
Default Implementation
getClass().getName() + '@' + Integer.toHexString(hashCode())Example output: Employee@4a54c0de, where:
Employee→ Class Name4a54c0de→ Hash code (hexadecimal)
Overriding toString()
class Employee {
int id;
String name;
@Override
public String toString() {
return id + " " + name;
}
}
Employee e = new Employee();
e.id = 101;
e.name = "John";
System.out.println(e);101 JohnReal-world Usage
Useful for logging, debugging, API responses and console output.
#2. equals()
Purpose
Compares two objects. The default implementation compares memory addresses.
Employee e1 = new Employee();
Employee e2 = new Employee();
System.out.println(e1.equals(e2));falseBecause both objects are stored at different memory locations.
Overriding equals()
class Employee {
int id;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
return id == other.id;
}
}Now two employees having the same id are considered equal.
#3. hashCode()
Purpose
Returns an integer hash value. Used heavily by HashMap, HashSet, Hashtable and ConcurrentHashMap.
Why Needed?
Imagine a HashMap. Instead of searching every object, Java computes hashCode() and directly jumps to the correct bucket. Search becomes much faster.
Contract
If a.equals(b) is true, then a.hashCode() == b.hashCode() must also be true.
The reverse is not guaranteed. Different objects can have the same hash code (hash collision).
Example
@Override
public int hashCode() {
return Objects.hash(id);
}equals() vs hashCode()
| equals() | hashCode() |
|---|---|
| Compares equality | Generates hash value |
Returns boolean | Returns int |
| Used after bucket lookup | Used before bucket lookup |
| Logical comparison | Fast indexing |
HashMap Internal Flow
#4. clone()
Purpose
Creates a copy of an object.
class Employee implements Cloneable {
@Override
protected Object clone()
throws CloneNotSupportedException {
return super.clone();
}
}Usage:
Employee e2 = (Employee) e1.clone();Shallow Copy
Both copied objects refer to the same nested object.
Deep Copy
Every referenced object is also copied. Preferred in enterprise applications.
#5. getClass()
Returns runtime class information.
Employee e = new Employee();
System.out.println(e.getClass().getName());EmployeeUsed in reflection, frameworks, Spring and Hibernate.
#6. wait()
Makes the current thread wait until another thread notifies it. Must be called inside a synchronized block.
synchronized (obj) {
obj.wait();
}#7. notify()
Wakes one waiting thread.
synchronized (obj) {
obj.notify();
}#8. notifyAll()
Wakes every waiting thread.
synchronized (obj) {
obj.notifyAll();
}wait() vs sleep()
| wait() | sleep() |
|---|---|
Object class | Thread class |
| Releases lock | Doesn't release lock |
Needs synchronized | Doesn't need synchronized |
| Used for inter-thread communication | Used for delaying execution |
#9. finalize()
Called before garbage collection.
protected void finalize() {
}Current Status
Use these instead:
- try-with-resources
AutoCloseableCleanerAPI
#Native Methods
Some Object class methods are native — implemented using platform-specific code. Examples:
hashCode()wait()notify()notifyAll()
#Interview Questions
Q1Can we create an object of Object class?
Yes.
Object obj = new Object();Q2Can Object class be inherited?
Yes. Every class inherits it automatically.
Q3Why override toString()?
For meaningful output instead of Employee@4a54c0de.
Q4Why override hashCode() with equals()?
Because hash-based collections rely on both methods.
Q5Can two unequal objects have the same hashCode?
Yes. This is called a hash collision.
Q6Can two equal objects have different hashCodes?
No. That violates the hashCode contract.
Q7Why is wait() inside Object instead of Thread?
Because the monitor (lock) belongs to the object, not the thread.
Q8Can clone() copy private variables?
Yes. It copies the object's state, including private fields.
Q9Is finalize() guaranteed to execute?
No. The JVM does not guarantee when or even if it will run.
Q10Which Object methods are used most in enterprise applications?
toString(), equals(), hashCode() and getClass().
The thread-related methods (wait(), notify(), notifyAll()) are less common in modern applications because higher-level concurrency utilities are often preferred.
#Common Mistakes
- Overriding
equals()withouthashCode(). - Using
==instead ofequals()for object comparison. - Relying on
finalize()for resource cleanup. - Using
clone()for deep copying without handling nested objects.
#Best Practices
- Override
toString()for readable logging. - Always override
equals()andhashCode()together. - Prefer copy constructors or factory methods over
clone()for complex objects. - Use
getClass()orinstanceofappropriately depending on equality semantics. - Prefer modern concurrency utilities (such as executors and locks) over low-level
wait()/notify()where appropriate.
#Quick Revision
- Object Class
- toString()
- equals()
- hashCode()
- clone()
- getClass()
- wait()
- notify()
- notifyAll()
- finalize()deprecated
#Chapter Summary
After completing this chapter, you should be able to:
- Explain why every Java class inherits from
Object. - Understand the purpose and implementation of all major
Objectclass methods. - Correctly implement
equals()andhashCode(). - Explain how
HashMapuses hashing internally. - Differentiate shallow copy from deep copy.
- Explain
wait(),notify(), andnotifyAll()for inter-thread communication. - Answer common interview questions related to the
Objectclass with confidence.