아이템 17 - 변경 가능성을 최소화 하라.
JAVA ·불변 클래스
- 인스턴스의 내부 값을 수정할 수 없는 클래스
- 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다.
불변 클래스를 만드는 다섯 가지 규칙
- 객체의 상태를 변경하는 메서드를 제공하지 않는다.
- 클래스를 확장할 수 없도록 한다.
- 클래스를 final로 선언한다.
- 생성자의 접근지시자를 private 또는 package-private로 하고 정적팩터리
- 모든 필드를 final로 선언한다.
- 모든 필드를 private으로 선언한다.
- 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다.
- 클라이언트에서 객체의 참조를 가리킬 수 없도록 방어적 복사를 수행하라.
불변 클래스의 장점
- 함수형 프로그맹에 적합하다.
- 피연산자에 함수를 적용한 결과를 반환하지만 피연산자가 바뀌지는 않는다.
- 불변 객체는 단순하다.
- 불변 객체는 근본적으로 스레드 안전하여 따로 동기화할 필요가 없다.
- 불변 객체는 안심하고 공유할 수 있다.
- 최대한 재사용하자( ex) 상수, public static final)
- 불변 객체 끼리는 내부 데이터를 공유할 수 있다.
- 객체를 만들 때 불변 객체로 구성하면 이점이 많다.
- 실제 원자성을 제공한다.
- 자기 자신이나 매개변수의 값이 변하지 않는다.
불변 클래스의 단점
- 값이 다르다면 별도의 객체를 만들어야 한다.
- “다단계 연산”을 제공하거나, “가변 동반 클래스”를 제공하여 대처할 수 있다.
- 다단계 연산 : 한 번에 여러 개의 연산
- 가변 동반 클래스 : 값을 바꿔줄 수 있는 동반 클래스
- “다단계 연산”을 제공하거나, “가변 동반 클래스”를 제공하여 대처할 수 있다.
불변 클래스 만들 때 고려할 것
- 상속을 막을 수 있는 또 다른 방법
- private 또는 package-private 생성자를 만들고 정적 팩터리를 제공하는 방법
- 확장이 가능하다. 다수의 package-private 구현 클래스를 만들 수 있다.
- 정적 팩터리를 통해 여러 구현 클래스 중 하나를 활용할 수 있는 유연성을 제공하고 객체 캐싱 기능으로 성능을 향상 시킬 수도 있다.
- 재정의가 가능한 클래스는 방어적인 복사를 사용해야 한다.
- 모든 “외부에 공개하는” 필드가 final이어야 한다.
- 계산 비용이 큰 값은 해당 값이 필요로 할 때 (나중에) 계산하여 final이 아닌 필드에 캐시해서 쓸 수도 있다.