Language/Java

[Java] 불변객체(Immutable Object)

anxi 2024. 4. 16. 19:01

이번 글의 주제는 불변객체(Immutable Object)이다. 

이 주제 역시 면접에서 질문을 받았었다.

면접관님 : 불변객체가 뭐예요?
나 : 내부 데이터를 변경할 수 없는 객체를 의미합니다..
면접관님 : 불변객체를 쓰는 이유가 뭐예요?
나 : 객체지향의 특징 중 캡슐화때문이라고 할 수 있습니다. 캡슐화를 통해 객체는 외부에서 접근되지 않고 ~~~~~

 

위와 같이 답변을 했지만,, 사실 불변객체가 말 그대로 "내부 데이터를 변경하지 못하는 객체"라고만 알고 있어서 이번 기회에 알아보고자 한다 !

 

불변 클래스

불변객체를 알아보기 전에 불변 클래스부터 알아보자 !

 

불변클래스란 인스턴스 내부의 값을 수정할 수 없는 클래스를 말한다.

 

그렇다면 불변클래스를 만드는 방법은 뭐가 있을까?

  • 객체의 상태를 변경하는 메소드를 제공하지 않는다. (ex. Setter)
  • 클래스를 확장할 수 없게 한다.
    • 상속이 가능할 경우, 하위 클래스는 오버라이딩을 통해 불변을 보장할 수 없기 때문에 상속을 막는다.
      • 모든 생성자를 private으로 만들거나, 정적 팩토리 메서드를 제공한다.
  • 모든 필드를 final로 선언한다.
  • 모든 필드를 private으로 선언한다.
  • 자신 외에는 내부 가변 컴포넌트에 접근할 수 없도록 한다.
    • 가변 컴포넌트 (배열, Collection ,,,) 를 가지는 필드가 하나라도 있으면 클라이언트에서 참조를 얻을 수 없도록 해야한다. 이때 "방어적 복사"를 수행한다.

불변객체 장점

  • 단순하다.
    • 생성 시점의 상태를 파괴될 때까지 보존하므로 믿고 사용할 수 있다.
  • Thread Safe하여 동기화할 필요가 없다.
    • 다른 Thread에 영향을 줄 수 없으므로 안심하고 공유할 수 있다.
  • 자유롭게 공유할 수 있으며, 불변객체끼리는 내부 데이터를 공유할 수 있다.
  • 불변객체를 구성요소로 사용하면 사용 객체도 불변을 유지하기 쉽다.
  • 실패 원자성(failure atomicity)을 제공한다.
    • 실패 원자성 : 메서드에서 예외가 발생한 후에도 그 객체는 호출 전과 같은 유효한 상태여야 한다는 성질
    • 불변객체의 메서드는 내부 상태를 바꾸지 않으므로 이 성질을 만족한다.

불변객체 단점

  • 값이 다르면 반드시 독립된(식별자가 다른) 객체로 만들어야 한다.
    • 만약 String의 경우, String a = new String("abc") 에서 bc로 변경하려면 새로운 객체를 만들어야 한다.