Back to Object Class, equals & hashCode
Q2Question 2 of 9

What is the difference between Object and Objects?

Key Concepts
  • Object (java.lang.Object): the root class, parent of every Java class
  • Objects (java.util.Objects): a utility class with static helper methods (since Java 7)
  • Objects.equals(a, b): null-safe equals comparison
  • Objects.hash(fields...): convenient multi-field hash code generation
  • Objects.requireNonNull(x, msg): throws NPE with a clear message if x is null
  • Objects.toString(obj, defaultValue): null-safe toString

Definition

Object is the root class of all Java classes. Objects (java.util.Objects) is a utility class with null-safe static helpers: equals, hash, requireNonNull, toString.

Two different things:

  • Object (java.lang.Object): The root class. Every class extends it. Provides instance methods: toString, equals, hashCode.
  • Objects (java.util.Objects): A utility class since Java 7. Provides static helper methods for null-safe operations.

Object is the bank template form. Objects is the office toolbox with null-safe stamps, validators, and comparison tools.

Understanding the Concepts

Key Objects utility methods

JAVA
import java.util.Objects;

// Null-safe equals
String a = null;
String b = "SAV2001";
Objects.equals(a, b);     // false (no NPE even though a is null)
Objects.equals(null, null); // true

// Multi-field hash code
int hash = Objects.hash(accountId, holderName, balance);

// Null check with message
public Account(String id) {
    this.accountId = Objects.requireNonNull(id, "accountId must not be null");
    // throws NullPointerException with the message if id is null
}

// Null-safe toString
Objects.toString(nullObj, "N/A");  // "N/A" instead of NPE

// Check index bounds (Java 9+)
Objects.checkIndex(index, array.length);  // throws IndexOutOfBoundsException if invalid

Using in equals and hashCode implementations

JAVA
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Account other)) return false;
    return Objects.equals(accountId, other.accountId)
        && Objects.equals(balance, other.balance);
}

@Override
public int hashCode() {
    return Objects.hash(accountId, balance);
}

What should a senior engineer know?

  • Objects.requireNonNull is the standard for constructor/method parameter validation in modern Java.
  • Objects.requireNonNullElse(obj, defaultValue) (Java 9+) returns defaultValue if obj is null.
  • Objects.equals uses the target's equals method if the first argument is non-null.

What are common mistakes?

A common mistake is overriding equals() without overriding hashCode(), which breaks HashMap and HashSet behavior.

Wrong approach:

JAVA
package com.bank.model;

public class Account {
    private String accountId;

    // WRONG: overrides equals but not hashCode
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Account)) return false;
        return accountId.equals(((Account) o).accountId);
    }
    // Missing hashCode override!
}
JAVA
// This breaks HashMap lookups
Map<Account, String> map = new HashMap<>();
Account a1 = new Account("SAV2001");
map.put(a1, "Rajesh");
Account a2 = new Account("SAV2001");
System.out.println(map.get(a2));  // null! Different hashCode

Correct approach:

JAVA
package com.bank.model;

import java.util.Objects;

public class Account {
    private String accountId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Account)) return false;
        return accountId.equals(((Account) o).accountId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(accountId);
    }
}

Now both a1 and a2 produce the same hash code, so HashMap lookups work correctly.

What are the edge cases?

Edge cases can cause unexpected behavior in banking applications. Here are some to watch for.

JAVA
package com.bank.edge;

public class EdgeCaseDemo {
    public static void main(String[] args) {
        // Edge case 1: null handling
        String accountId = null;
        try {
            System.out.println(accountId.length());
        } catch (NullPointerException e) {
            System.out.println("Null account ID");
        }

        // Edge case 2: empty vs null
        String emptyId = "";
        System.out.println(emptyId.isEmpty());  // true
        System.out.println(emptyId == null);     // false

        // Edge case 3: boundary values
        java.math.BigDecimal zero = java.math.BigDecimal.ZERO;
        java.math.BigDecimal negativeBalance = new java.math.BigDecimal("-0.01");
        System.out.println(zero.compareTo(negativeBalance) > 0);  // true
    }
}
TEXT
Null account ID
true
false
true

Always test with null values, empty strings, boundary values, and negative amounts in banking applications.

What are common interview follow-up questions?

Interviewers often follow up with these related questions:

  • How does this concept apply to a high-throughput banking transaction system?
  • What are the performance implications in a production environment?
  • How would you debug issues related to this concept?
  • What tools would you use to monitor this in production?
  • How does this behave differently in Java 8 vs Java 17+?

When answering follow-up questions, always relate your answer back to practical experience. For example, at National Bank of India, Rajesh debugged a production issue related to this concept by using JFR recordings and heap dumps. Providing concrete examples from banking systems shows the interviewer that you understand both the theory and the practice.

Visual Overview

DIAGRAM
  Object (java.lang.Object):     root class, parent of all
  Objects (java.util.Objects):    utility class, static helpers

  Objects.equals(a, b)        → null-safe equality
  Objects.hash(f1, f2, ...)   → multi-field hashCode
  Objects.requireNonNull(x)   → NPE with message if null
  Objects.toString(x, "N/A")  → null-safe toString

Key Takeaway

Object is the root class of all Java classes. Objects is a utility class with null-safe static helpers. Use Objects.equals() for null-safe comparison, Objects.hash() for multi-field hash codes, and Objects.requireNonNull() for parameter validation.

One sentence to remember: Object is the parent class, Objects is the utility toolbox – use Objects.equals for null-safe comparison and Objects.hash for hash codes.

---

Share
Use ← → arrow keys to navigate