The Object Superclass

Introduction

Object is the root class in Java. Every class automatically inherits from Object class.

class MyClass { }
// Automatically: class MyClass extends Object { }

Hierarchy

       Object (Root)
          |
    All Java Classes

Important Methods in Object Class

  1. toString()
  2. equals(Object obj)
  3. hashCode()
  4. getClass()
  5. clone()
  6. finalize() (deprecated)
  7. wait(), notify(), notifyAll() (threading)

toString() Method

Returns string representation of object.

Default Implementation:

class Student {
    String name;
    int rollNo;

    Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student("John", 101);
        System.out.println(s);  // Student@hashcode
        System.out.println(s.toString());  // Same
    }
}

Overriding toString():

class Student {
    String name;
    int rollNo;

    Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }

    @Override
    public String toString() {
        return "Student[name=" + name + ", rollNo=" + rollNo + "]";
    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student("John", 101);
        System.out.println(s);  // Student[name=John, rollNo=101]
    }
}

equals() Method

Compares two objects for equality.

Default Implementation:

// Default equals() compares references
Student s1 = new Student("John", 101);
Student s2 = new Student("John", 101);

System.out.println(s1.equals(s2));  // false (different objects)
System.out.println(s1 == s2);       // false (same as default equals)

Overriding equals():

class Student {
    String name;
    int rollNo;

    Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        Student student = (Student) obj;
        return rollNo == student.rollNo && name.equals(student.name);
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("John", 101);
        Student s2 = new Student("John", 101);

        System.out.println(s1.equals(s2));  // true (same data)
    }
}

hashCode() Method

Returns hash code value for object.

Rule:

If equals() returns true, hashCode() must return same value.

class Student {
    String name;
    int rollNo;

    Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        Student student = (Student) obj;
        return rollNo == student.rollNo && name.equals(student.name);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + rollNo;
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("John", 101);
        Student s2 = new Student("John", 101);

        System.out.println(s1.hashCode());  // Same
        System.out.println(s2.hashCode());  // Same
    }
}

getClass() Method

Returns runtime class of object.

class Animal { }
class Dog extends Animal { }

public class Main {
    public static void main(String[] args) {
        Animal a = new Dog();

        System.out.println(a.getClass());         // class Dog
        System.out.println(a.getClass().getName()); // Dog
        System.out.println(a.getClass().getSimpleName()); // Dog

        // Check type
        if (a.getClass() == Dog.class) {
            System.out.println("It's a Dog");
        }
    }
}

Complete Example

class Person {
    private String name;
    private int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Override toString()
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }

    // Override equals()
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }

    // Override hashCode()
    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("John", 25);
        Person p2 = new Person("John", 25);
        Person p3 = new Person("Alice", 30);

        // toString()
        System.out.println(p1);  // Person{name='John', age=25}

        // equals()
        System.out.println("p1 equals p2: " + p1.equals(p2));  // true
        System.out.println("p1 equals p3: " + p1.equals(p3));  // false

        // hashCode()
        System.out.println("p1 hash: " + p1.hashCode());
        System.out.println("p2 hash: " + p2.hashCode());  // Same as p1

        // getClass()
        System.out.println("Class: " + p1.getClass().getSimpleName());
    }
}

All Object Methods

public class Object {
    public String toString() { }
    public boolean equals(Object obj) { }
    public int hashCode() { }
    public final Class<?> getClass() { }
    protected Object clone() throws CloneNotSupportedException { }
    protected void finalize() throws Throwable { }  // Deprecated
    public final void wait() throws InterruptedException { }
    public final void notify() { }
    public final void notifyAll() { }
}

Inherited by All Classes

class MyClass {
    // Automatically has:
    // - toString()
    // - equals()
    // - hashCode()
    // - getClass()
    // - etc.
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();

        System.out.println(obj.toString());     // Available
        System.out.println(obj.equals(obj));    // Available
        System.out.println(obj.hashCode());     // Available
        System.out.println(obj.getClass());     // Available
    }
}

Why Override?

1. toString() - Better Display:

// Without override: Student@15db9742
// With override: Student[name=John, rollNo=101]

2. equals() - Meaningful Comparison:

// Without override: compares references
// With override: compares actual data

3. hashCode() - Collections:

// Needed for HashMap, HashSet
// Must override with equals()

Object as Parameter

class Utility {
    // Accepts any object
    static void display(Object obj) {
        System.out.println(obj.toString());
        System.out.println("Class: " + obj.getClass().getSimpleName());
    }
}

public class Main {
    public static void main(String[] args) {
        Utility.display("Hello");        // String
        Utility.display(123);            // Integer
        Utility.display(new Student());  // Student
    }
}

Object Array

public class Main {
    public static void main(String[] args) {
        Object[] objects = new Object[3];
        objects[0] = "Hello";
        objects[1] = 123;
        objects[2] = new Student("John", 101);

        for (Object obj : objects) {
            System.out.println(obj);  // Calls toString()
        }
    }
}

equals() Contract

  1. Reflexive: x.equals(x) must be true
  2. Symmetric: If x.equals(y), then y.equals(x)
  3. Transitive: If x.equals(y) and y.equals(z), then x.equals(z)
  4. Consistent: Multiple calls return same result
  5. null: x.equals(null) must be false

hashCode() Contract

  1. Consistent: Same object, same hash (if not modified)
  2. equals() → hashCode(): If equals() true, hashCode() must be same
  3. Not required: Different objects can have same hash (collision)

Quick Reference

class Example {
    // Override toString()
    @Override
    public String toString() {
        return "Example object";
    }

    // Override equals()
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        // Compare fields
        return true;
    }

    // Override hashCode()
    @Override
    public int hashCode() {
        // Calculate based on fields
        return 0;
    }
}

// Usage
Example e = new Example();
e.toString();         // Custom string
e.equals(other);      // Custom comparison
e.hashCode();         // Custom hash
e.getClass();         // Runtime class

Exam Tips

Remember:

  1. Object is root of all classes
  2. Every class extends Object (implicit)
  3. toString() returns string representation
  4. equals() compares objects
  5. hashCode() returns hash value
  6. getClass() returns runtime class
  7. Override equals() and hashCode() together
  8. Default equals() compares references
  9. Used for polymorphism
  10. All classes inherit Object methods

Common Questions:

  • What is Object class?
  • Methods in Object class?
  • Why override toString()?
  • Why override equals()?
  • What is hashCode()?
  • equals() and hashCode() contract?
  • What is getClass()?
  • Is Object class inherited?