Why is java.lang.Object the universal superclass, and what does every class get from it?
answer
- Object = root of the class tree
- no extends → implicitly extends Object
- gives toString/equals/hashCode/getClass/clone/wait-notify
- override equals + hashCode together
- primitives are NOT objects; wrappers are
basics
~10 sEvery Java class extends Object directly or indirectly, so all objects share a common type and inherit methods like toString(), equals(), and hashCode().
solid answer
~40 sjava.lang.Object sits at the root of Java's class hierarchy: any class without an explicit extends clause implicitly extends Object, and every chain of superclasses eventually reaches it. This gives Java a single rooted inheritance tree, which is what lets a variable of type Object hold any reference and lets generic collections work with any object. From Object every class inherits methods including toString(), equals(Object), hashCode(), getClass(), clone(), and the thread-coordination methods wait()/notify(). Many of these have default implementations you typically override — for example, equals() and hashCode() default to identity comparison, so value classes override them together. Primitives are not objects and don't extend Object, but their wrapper classes do. records and enums also descend from Object (via Record/Enum).
code
java · 13 linesclass Point {
final int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point p)) return false;
return x == p.x && y == p.y;
}
@Override public int hashCode() { return 31 * x + y; } // override together
@Override public String toString() { return "(" + x + "," + y + ")"; }
}
// Point silently extends Object and gets these defaults until overridden.go deeper
Knows every class extends Object and inherits toString(), equals(), and hashCode().
Explains the implicit extends Object, lists the key inherited methods, and knows the equals/hashCode pairing rule.
Details the equals/hashCode contract and its effect on hash collections, identity-vs-value semantics, and which Object methods are final.
Reasons about identity vs equality across distributed/persistence layers, immutability and hashCode caching trade-offs, and consistent equality contracts in large domain models.
## What 'universal superclass' means Java arranges all classes into a single tree of inheritance, and the **root** of that tree is `java.lang.Object`. 'Universal superclass' means **every** class is a descendant of `Object`: either it extends `Object` directly, or it extends some class that (eventually) extends `Object`. ## How a class ends up extending Object If you declare a class with no `extends` clause, the compiler implicitly inserts `extends Object`: ```java class Foo {} // really: class Foo extends Object class Bar extends Foo {} // Bar -> Foo -> Object ``` Follow any class up its superclass chain and you always arrive at `Object`. `Object` itself has no superclass — it is the top. ## Why having a single root is useful Because every object is-a `Object`: - A reference typed `Object` can refer to *anything*: `Object o = "hi";` or `Object o = new Dog();`. - Before generics, collections stored `Object`; even today the system relies on this common base. - Reflection, serialization frameworks, and `==`/`instanceof` machinery can treat all objects uniformly. ## The methods every object inherits From `Object`, every class inherits these instance methods: - **`toString()`** — a string representation; default is `ClassName@hexHashCode`. Usually overridden for readable output. - **`equals(Object other)`** — logical equality; the default compares object identity (same reference, like `==`). Value types override it to compare contents. - **`hashCode()`** — an int used by hash-based collections (`HashMap`, `HashSet`). The contract: equal objects must return equal hash codes, so you override it whenever you override `equals()`. - **`getClass()`** — returns the runtime `Class` object; cannot be overridden (final). - **`clone()`** — makes a field-by-field copy (protected; requires `Cloneable`). - **`wait()`, `notify()`, `notifyAll()`** — low-level thread coordination tied to the object's monitor; final. - **`finalize()`** — legacy cleanup hook, deprecated/removed in modern Java. ## The equals/hashCode contract (most-tested point) The defaults treat each object as equal only to itself. For a 'value' class (two instances with the same data should be equal), you override **both** `equals` and `hashCode` consistently. If you override only one, hash-based collections misbehave — e.g. two 'equal' keys land in different buckets. ## What does NOT extend Object - **Primitives** (`int`, `double`, `boolean`, …) are not objects and do not extend `Object`. Their **wrapper** classes (`Integer`, `Double`, …) do. - **Interfaces** do not extend `Object`, but a reference of an interface type still gives you `Object`'s methods, and any object you assign to it is an `Object`. - **Arrays** are objects and extend `Object`. - **records** extend `java.lang.Record` (which extends `Object`) and auto-generate `equals`/`hashCode`/`toString`; **enums** extend `java.lang.Enum` (which extends `Object`).
- Why must you override hashCode() whenever you override equals()?The contract says equal objects must have equal hash codes. Hash-based collections like HashMap use hashCode to find buckets; if equal objects have different hashes, lookups fail.
- Do primitive types like int extend Object?No. Primitives are not objects. Their wrapper classes (Integer, etc.) extend Object, and autoboxing converts between them.
Object is the common ancestor at the very top of a family tree everyone descends from — so everyone is born with the same basic toolkit (a name to print, a way to compare, an identity).
saying these in an interview costs you the question
- Saying primitives extend Object
- Overriding equals() without hashCode() (or vice versa)
- Claiming you must write 'extends Object' explicitly
- Thinking getClass() or wait() can be overridden (they are final)