가끔 객체를 생성했는데 사이드이팩트로 변경되어서는 안될 값이 같이 변경되는 이슈가 있을 수 있다.
(사이드 이펙트(Side Effect)는 프로그래밍에서 어떤 계산이 주된 작업 외에 추가적인 부수 효과를 일으키는 것을 말함.)
이럴때 불변하도록 해당 부분을 private final로 제약을 두어
불변객체! 말그대로 바뀌지않는 객체를 만들면 해결가능하다.
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