← SEARCHABLE ARCHIVE
Java · 2026-07-22

Java from Basics to Mastery — Part 3

Designing Objects, Encapsulation, and Immutable Values

INTERACTIVE READING MODE →

The articles written on this blog were created with the goal of teaching. Also, the information in the article may be incorrect, so please be careful.

An object binds related state and behavior within a single boundary. Encapsulation is not about hiding fields unconditionally, but putting rules into a class so that only valid states can be created.

Creating a valid object with a constructor

public final class Player {
    private final String name;
    private int health;

    public Player(String name, int health) {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("name is required");
        }

        this.name = name;
        this.health = Math.max(0, health);
    }

    public void takeDamage(int amount) {
        if (amount > 0) {
            health = Math.max(0, health - amount);
        }
    }

    public int getHealth() {
        return health;
    }
}

The outside cannot change health directly; it only changes it through a rule called takeDamage. An object whose constructor has been completed satisfies the condition that its name and health are valid.

References can point to the same object

Player first = new Player("Rose", 100);
Player second = first;

second.takeDamage(20);
System.out.println(first.getHealth()); // 80

In the second, the object was not copied, but the reference pointing to the same Player was copied. If independent copies are required, you must explicitly design which fields will be copied.

Creating immutable values

public final class ItemKey {
    private final int id;
    private final String grade;

    public ItemKey(int id, String grade) {
        this.id = id;
        this.grade = grade;
    }
}

If you make a field final and do not provide a change method, its state will not change after creation. However, if the field is a mutable collection, you should consider defensive copying or read-only views.

The point of object design is not to create both getters and setters. Who can change the state and what conditions must always be maintained are expressed through public methods of the class.