본문 바로가기
  • 시 쓰는 개발자
1일 1개념정리 (24년 8월~)/Java

1일1개 (21) - 불변객체란 ?

by poetDeveloper 2024. 8. 30.

1일 1개념정리 24.08.09.금 ~ 

 

큰 결정에 큰 동기가 따르지 않을 때도 있다. 하지만 큰 결심이 따라야 이뤄낼 수 있다.

무조건 무조건 1일 1개의 개념 정리하기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!


#21. 불변객체

Java에서 "불변 객체"란, 한번 생성된 이후에 속성이나 필드가 변경되지 않는 객체를 의미한다. 일단 한번 생성되면 값을 바꿀 수 없고, 객체의 메소드들도 객체의 상태를 수정하지 않게 설계되어 있다.

 

불변객체 만드는 여러 방법

우리의 목표는 객체가 변하지 않게 하는 것이다. 이를 위한 여러 방법이 있다.

 

1. 모든 필드가 final

이전에 포스팅 16번째 시간에서 final에 대해 배웠는데, final은 값을 바꾸지 못하게 하여 모든 값을 상수취급한다고 하였다. 참고 - https://100won-developer.tistory.com/entry/1%EC%9D%BC1%EA%B0%9C-16-%EC%9E%90%EB%B0%94-final 그러므로, 불변 객체의 모든 필드는 final로 선언된다. 이를 통해 객체의 상태가 변경되지 않음을 보장한다.

 

2. 객체 자체에 대한 변경을 허용하지 않음

불변 객체는 객체 자체가 변경되지 않도록 설계된다. 뭔소리냐면, 객체 내부에 값을 변경하는 메소드 자체가 없다는 뜻이다. ex) @Setter 이런 기능하는 메소드 자체가 아예 없음. 아래 코드 예시도 보면 getOOO만 있지, setOOO은 없음.

 

3. 방어적 복사

불변 객체 내에서 참조하는 다른 객체들이 있다면, 해당 객체들 역시 불변 객체이거나, 그렇지 않다면 방어적 복사(defensive copy)를 통해 외부에서 그 객체들의 상태를 변경할 수 없도록 방지한다. 아래 코드로 예시를 들어보자.

import java.util.Date;

public final class ImmutableEvent {
    private final String title;
    private final Date date;

    public ImmutableEvent(String title, Date date) {
        this.title = title;
        this.date = new Date(date.getTime()); // 방어적 복사
    }

    public String getTitle() {
        return title;
    }

    public Date getDate() {
        return new Date(date.getTime()); // 방어적 복사
    }
}

이 코드에서 Date 객체는 가변 객체이기 때문에 생성자와 Getter를 쓸 때 복사본을 사용한다. 이렇게 하면 외부에서 원본 Date 객체를 변경하더라도 불변객체 내에 있는 date에는 영향을 주지 않는다.

 

불변 객체의 장점

  1. 스레드 안전성 : 불변 객체는 상태가 변경되지 않기 때문에 여러 스레드가 동시에 객체에 접근하더라도 안전하다. 그래서 동기화 없이도 스레드 안전성을 보장할 수 있다.
  2. 단순성 : 객체의 상태가 불변이기 때문에 상태 변화를 추적할 필요가 없어 코드가 단순해진다.
  3. 캐싱과 재사용 : 상태가 변하지 않으므로, 동일한 값을 가지는 객체를 캐싱하거나 재사용할 수 있다. 예를 들어 String 클래스는 불변 객체로 설계되어 있어서 String Pool에서 동일한 문자열을 공유할 수 있다. 이처럼 재사용하는 것은 가비지 컬렉션의 성능을 올려주는 부수적인 효과도 보인다. 왜냐하면 재사용하면 제거 대상 자체가 줄기 때문이다.