← SEARCHABLE ARCHIVE
Java · 2026-07-22

Java 기초부터 마스터까지 — 3화

객체, 캡슐화, 불변 값 설계하기

INTERACTIVE READING MODE →

본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.

객체는 관련된 상태와 동작을 하나의 경계 안에 묶는다. 필드를 무조건 숨기는 것이 아니라 유효한 상태만 만들 수 있도록 규칙을 클래스에 두는 것이 캡슐화다.

생성자로 유효한 객체 만들기

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;
    }
}

외부가 health를 직접 바꾸지 못하고 takeDamage라는 규칙을 통해서만 변경한다. 생성자가 끝난 객체는 이름과 체력이 유효하다는 조건을 만족한다.

참조는 같은 객체를 가리킬 수 있다

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

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

second에 객체가 복제된 것이 아니라 같은 Player를 가리키는 참조가 복사되었다. 독립된 복사본이 필요하면 어떤 필드를 복사할지 명시적으로 설계해야 한다.

불변 값 만들기

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

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

필드를 final로 두고 변경 메서드를 제공하지 않으면 생성 후 상태가 바뀌지 않는다. 다만 필드가 변경 가능한 컬렉션이라면 방어적 복사나 읽기 전용 뷰까지 고려해야 한다.

객체 설계의 핵심은 getter와 setter를 모두 만드는 것이 아니다. 누가 상태를 바꿀 수 있고 어떤 조건이 항상 유지되어야 하는지를 클래스의 공개 메서드로 표현하는 것이다.