Object Class

Basic Java
≈ 3 min read

The root of the class hierarchy

All Java classes share a common point in the hierarchy — java.lang.Object. Object itself is at the top, and every other class inherits from it directly or indirectly. For an ordinary class declaration such as class User {} with no explicit extends, the immediate superclass is Object.

That is why the methods of Object are available to objects of many different classes. They form the common minimum set of behavior that every object has regardless of what domain model it represents.

Object as a common type

Because Object is the common ancestor, a variable of this type can hold a reference to an object of any class. This is a regular use of the polymorphism you already know: the reference type is more general, while the object keeps its actual class.

class User {
}

Object value = new User();

System.out.println(value.getClass().getSimpleName()); // User

Here the variable has the type Object, but it still refers to a User object. Through such a variable, you can directly access only the methods known to the Object type. Methods declared only in User cannot be called through it.

Arrays are objects too, so a reference to an array can be stored in a variable of type Object. Primitive types such as int, however, are not part of the class hierarchy.

What Object gives every object

Object defines methods that cover several basic tasks:

  • getClass() returns the object's runtime class;
  • equals(), hashCode(), and toString() provide standard extension points for equality, hashing, and the object's text representation;
  • clone() provides a basic object-copying mechanism;
  • wait(), notify(), and notifyAll() are related to an object's monitor and low-level thread coordination.

For now, the important part is to see the overall picture rather than memorize the contracts of all these methods. We will examine equals(), hashCode(), and toString() in detail in the next topic, while the waiting and notification methods will become relevant later when we study multithreading.

Do not use finalize() to release resources. In Java 25, this method is deprecated and marked for removal. Modern code manages resources in other ways, so finalize() should be treated as a legacy API rather than a tool for new code.

Why a common ancestor matters

Object gives Java a shared baseline of behavior for all objects. Because of this, completely different classes have common methods and can be used in places that require the most general object type.

At the same time, Object does not replace more precise types. If code specifically needs a User, it is better to declare the variable as User. The Object type is useful when you genuinely need to work with objects of different classes through a common contract.