What is the difference between a class and an object in Java, and how do you tell them apart in code?
A class is a description: the fields an object will have, the methods it can run, and the rules for constructing one. It exists as a type and as the bytecode that the class loader loads. An object is an instance: a particular piece of state living on the heap, created from that description. The class is shared; each object has its own copy of the fields.
Three practical ways to name the difference. The class is what you write in the source file. The object is what you create with new. And the class is what getClass() returns, so two objects are instances of the same class when their getClass() references are equal.
public class Main {
public static void main(String[] args) {
// The class is the blueprint; the object is the thing built from it.
Car car = new Car("Hatch", 2020);
System.out.println("car : " + car);
System.out.println("class of car : " + car.getClass().getName());
System.out.println("simple name : " + car.getClass().getSimpleName());
System.out.println("instanceof Car : " + (car instanceof Car));
// Two objects from the same class are distinct instances.
Car other = new Car("Saloon", 2021);
System.out.println("same instance : " + (car == other));
System.out.println("same class : " + (car.getClass() == other.getClass()));
}
}
class Car {
private final String body;
private final int year;
Car(String body, int year) {
this.body = body;
this.year = year;
}
@Override
public String toString() {
return body + " (" + year + ")";
}
}The output separates the two ideas neatly. The two cars are not the same object, so == on the references is false, but they come from the same class, so comparing their class objects is true. The identity check and the class check answer different questions, and confusing them is a common source of bugs.
One more distinction worth keeping straight: the class of an object is fixed for its lifetime. You cannot change an object's class at run time — getClass() is final — which is why the cast questions later in this topic all revolve around the static type of your reference, not the type of the object itself.