Skip to content
Java oop basics 7 min read

Classes & Objects

A class is a blueprint — it defines what data an object holds and what actions it can perform. An object is a concrete instance created from that blueprint at runtime. Almost everything you write in Java lives inside a class, and most of what you actually run involves objects.

Defining a Class

A class declaration starts with the class keyword, followed by the class name, and a pair of curly braces that contain the class body.

public class Car {
    // fields — data the object holds
    String brand;
    String color;
    int year;

    // method — behavior the object can perform
    void displayInfo() {
        System.out.println(year + " " + brand + " (" + color + ")");
    }
}
  • Fields (also called instance variables) store the state of each object. Every object gets its own copy.
  • Methods define behavior — reusable blocks of code that operate on the object’s fields.

Note: By convention, class names start with an uppercase letter and use PascalCase — Car, BankAccount, StudentRecord. See Naming Conventions for the full set of rules.

Creating Objects with new

To create an object you use the new keyword followed by the class name and parentheses (which calls the constructor):

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();   // create an object of type Car
        myCar.brand = "Toyota";
        myCar.color = "Red";
        myCar.year  = 2023;

        myCar.displayInfo();
    }
}

Output:

2023 Toyota (Red)

Three things happen on the line Car myCar = new Car();:

  1. new Car() allocates memory on the heap for a fresh Car object and calls its constructor.
  2. The variable myCar is created on the stack and holds a reference (memory address) to that heap object.
  3. You use the dot operator (.) to access the fields and methods of the object through that reference.

Multiple Objects from One Class

One class can produce as many objects as you need, and each object maintains its own independent state:

public class Main {
    public static void main(String[] args) {
        Car car1 = new Car();
        car1.brand = "Honda";
        car1.color = "Blue";
        car1.year  = 2021;

        Car car2 = new Car();
        car2.brand = "BMW";
        car2.color = "Black";
        car2.year  = 2024;

        car1.displayInfo(); // 2021 Honda (Blue)
        car2.displayInfo(); // 2024 BMW (Black)
    }
}

Output:

2021 Honda (Blue)
2024 BMW (Black)

car1 and car2 are two completely separate objects in memory. Changing car1.color has no effect on car2.

The Anatomy of a Class

Here is a more complete class that shows every major component in one place:

public class Student {

    // --- Fields (instance variables) ---
    private String name;   // private: only accessible inside this class
    private int    age;

    // --- Constructor ---
    public Student(String name, int age) {
        this.name = name;  // 'this' distinguishes the field from the parameter
        this.age  = age;
    }

    // --- Getter methods (accessors) ---
    public String getName() { return name; }
    public int    getAge()  { return age;  }

    // --- Setter methods (mutators) ---
    public void setAge(int age) {
        if (age > 0) this.age = age;
    }

    // --- Behavior ---
    public void introduce() {
        System.out.println("Hi, I'm " + name + " and I'm " + age + " years old.");
    }
}
public class Main {
    public static void main(String[] args) {
        Student s = new Student("Alice", 20);
        s.introduce();
        s.setAge(21);
        System.out.println("Updated age: " + s.getAge());
    }
}

Output:

Hi, I'm Alice and I'm 20 years old.
Updated age: 21

Tip: Making fields private and providing public getters/setters is called encapsulation. It protects your data from accidental or invalid changes. Read more at Encapsulation and Access Modifiers.

Anonymous Object

You can create an object and call a method on it without storing it in a variable. This is called an anonymous object — useful for one-off calls where you don’t need to reuse the reference:

new Student("Bob", 18).introduce();

Output:

Hi, I'm Bob and I'm 18 years old.

The object is created, introduce() runs, and then the object becomes eligible for garbage collection immediately since there is no reference to it.

Default Values of Fields

When you create an object without explicitly setting its fields, Java assigns sensible defaults:

TypeDefault Value
int, long, short, byte0
double, float0.0
booleanfalse
char'\u0000' (null char)
Any reference type (e.g., String)null

Warning: Local variables inside a method do not get default values — the compiler forces you to initialize them before use. Only instance fields (inside a class) get defaults.

Object References and Assignment

A variable of a class type holds a reference to an object, not the object itself. This has an important consequence when you assign one variable to another:

Car a = new Car();
a.brand = "Ford";

Car b = a;          // b now points to the SAME object as a
b.brand = "Tesla";

System.out.println(a.brand); // Tesla — a and b share the same object

Output:

Tesla

If you want a truly independent copy, you need to implement Object Cloning or write a copy constructor.

null References

A reference variable that has not been assigned an object holds null. Calling a method on a null reference throws a NullPointerException:

Car c = null;
c.displayInfo(); // NullPointerException at runtime!

Always check for null before dereferencing a variable you are not sure about, or use Optional (see Optional in the Java 8 features section).

Under the Hood

Understanding what the JVM does when you write new Car() makes a lot of subtle behavior click.

Memory Layout

  • Stack — Each thread has its own stack. Local variables (including object references) live here. Stack frames are created and destroyed as methods are called and return. Very fast, but limited in size.
  • Heap — One shared heap per JVM. All objects live here. The heap is managed by the Garbage Collector, which automatically reclaims memory when objects are no longer reachable.

When you write Car myCar = new Car():

  • A block of heap memory is allocated large enough to hold all of Car’s instance fields.
  • The fields are zero-initialized (defaults from the table above).
  • The constructor runs to set initial values.
  • myCar on the stack holds the 4- or 8-byte address (reference) of that heap block.

Object Header

Every Java object carries an invisible object header (typically 12–16 bytes) that the JVM uses internally. It contains:

  • A mark word — used for locking (synchronized), hash code caching, and GC age tracking.
  • A class pointer — a reference back to the class metadata (method table, vtable) stored in the Metaspace.

This is why even a completely empty object new Object() occupies at least 16 bytes on a modern 64-bit JVM.

Class Loading

The first time your code references Car, the ClassLoader reads Car.class from the classpath, parses the bytecode, and stores the class metadata in the JVM’s Metaspace. Subsequent new Car() calls reuse that already-loaded class — loading happens only once per class per ClassLoader.

Tip: For deep performance work, tools like Java Flight Recorder and jmap let you inspect heap usage and see exactly how many instances of each class exist at any point.

Class vs Object — A Quick Summary

ConceptClassObject
What it isBlueprint / templateInstance of a class
Exists in memory?In Metaspace (class metadata)On the heap
Created withclass keywordnew keyword
CountOne per JVM classloaderMany (as many as you create)
ExampleCarnew Car()

For a more detailed side-by-side, see Object vs Class.

  • Constructors — learn how constructors initialize objects, support overloading, and chain with this() and super().
  • Methods — define reusable blocks of behavior, understand parameters, return types, and method signatures.
  • this Keyword — how this refers to the current object instance and disambiguates field names from parameters.
  • static Keyword — fields and methods that belong to the class itself rather than any individual object.
  • Encapsulation — protect object state with private fields and controlled access via getters and setters.
  • Garbage Collection — understand how the JVM automatically reclaims heap memory from unreachable objects.
Last updated June 13, 2026
Was this helpful?