Java) 불변객체는 왜 private 일까?

나가을·2024년 4월 7일
2

java

목록 보기
1/12

가끔 객체를 생성했는데 사이드이팩트로 변경되어서는 안될 값이 같이 변경되는 이슈가 있을 수 있다.
(사이드 이펙트(Side Effect)는 프로그래밍에서 어떤 계산이 주된 작업 외에 추가적인 부수 효과를 일으키는 것을 말함.)

해결책?

이럴때 불변하도록 해당 부분을 private final로 제약을 두어
불변객체! 말그대로 바뀌지않는 객체를 만들면 해결가능하다.

왜 private으로 해야만 해?

private 말고 pulbic 으로 해도 되지 않을까!? 라는 의문이들었다.

그것에 대한 해답은 아래 코드로 알 수 있다.
예를 들어

 public class Immutable {
     public final char[] state = "Hi Mom".getChars();
     
     public char[] getState() {
         return state.clone();
     }
  }

다음과 같은 경우 불변객체가 수정 가능해 진다..!

  Immutable mu = new Immutable();
  mu.state[1] = 'o';

Java String은 불변이지만 비공개 최종 필드 중 하나는 변경 가능한 char[] 배열을 참조한다.
String 메서드는 배열 내용을 수정하지 않지만 배열 참조가 공개적이라면 다른 코드가 문자열 값을 변경하는 것을 막을 수 없다.

쉽게 풀어쓰자면
1. 가을이가 A를 가리키고 있음
2. 가을이는 이제 A밖에 못가리킴
3. 하지만 A 내부 자체에서 변화가 일어나는건 가능해짐.

물론 이는 유형이 변경 가능한 참조 유형인 필드에만 적용되지만,
이것이 필드를 비공개로 유지하는 것이 좋은 이유 중 하나이다!

두 번째 이유는 캡슐화이다. 필드를 비공개로 선언하면 구현 세부 정보가 숨겨져 원치 않는 교차 결합의 위험이 줄어든다. 이렇게 하지 않으면 다른 프로그래머는 불변의 내부에 의존하는 코드를 작성하고 싶은 유혹을 받을 수 있습니다. 그러면 상태 유형을 문자열로 변경하는 등 변경해야 하는 경우 문제가 발생할 수 있다.

추가)불변객체 변경법?

private final 로 만든 다음에 불변 객체의 값을 변경하고 싶다면 변경하고 싶은 값으로 새로운 불변 객체를 생성해야 한다.
이렇게 하면 기존 변수들이 참조하는 값에는 영향을 주지 않는다.

참고
https://stackoverflow.com/questions/28410386/in-immutable-class-why-fields-are-marked-as-private

profile
도라도라 코딩나라

0개의 댓글