불변 객체

객체를 공유하는 것 자체가 문제가 아닌, 공유된 객체의 값을 변경한 것이 문제의 직접적인 원인이다.

객체의 상태( 객체 내부의 값, 필드, 멤버 변수)가 변하지 않는 객체를 불변 객체라고 한다.

public class ImmutableAddress {
    private final String value;
    
    public ImmutableAddress(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
    
    @Override
    public String toString() {
        return "Address{" +
                "value='" + value + '\'' +
                '}';
    }
    // 불변 값을 가진 새로 생성된 불변 객체 반환
    public immutableAddress change(String newAddress){
        return new ImmutableAddress(newAddress);
    }
}
  • 내부 값이 변경되면 안됨. 따라서 value의 필드를 final로 선언

  • 값을 변경할 수 있는 setValue() 를 제거

  • 이 클래스는 생성자를 통해서만 값을 설정할 수 있고, 이후에는 값을 변경하는 것이 불가능하다.

여러 변수가 하나의 객체(인스턴스)를 참조하고 해당하는 객체의 값을 변경했기 때문에 문제가 발생한다.

address가 다른 인스턴스를 만들고 싶으면 새롭게 ImmutableAddress 인스턴스를 생성하면 된다.

불변 객체 정리

  • 자바는 무조건 값 기반

  • 만약 필드에 값을 저장한다면 final만 선언 하는 것으로 불변이 보장된다.

  • 근데 만약 참조값이라면 컬렉션이나 객체를 저장할 수 있다. 이러한 경우 컬렉션이나 객체를 참조하는 참조값은 변하지 않겠지만 컬렉션, 객체 내부의 값이 변경되거나 추가되는 것을 막을 수 없다. 이를 막으려면 해당 컬렉션이나 객체에 변경이 일어날 때 새로운 불변 객체를 반환시키자.

Last updated