생성 후 상태를 바꿀 수 없는 객체
즉, 힙 영역에서 객체가 가리키고 있는 데이터 자체의 변화가 불가능한 것
ex) Money의 필드 int형 money는 한 번 값을 할당하면 변경할 수 없다.
public class Money {
final private int money;
private Money(final int money) {
this.money = money;
}
}
가장 많이 사용하는 불변 객체는 바로 String입니다.
String name = "judy";
name = "juri";
이런 것이 가능한데, String은 왜 불변 객체일까요?
이는 name이 참조하는 “judy” 값이 변경되는 것이 아니라, “juri” 라는 새로운 객체를 만들고 그 객체를 name이 참조하게 하기 때문입니다.
즉, 불변 객체는 재할당은 가능하지만, 한 번 할당하면 내부 데이터를 변경할 수 없는 객체인 것이지요.
필드에 final 키워드를 붙이고, Setter 제거하여 불변을 보장합니다.
public class Money {
final private int money;
private Money(final int money) {
this.money = money;
}
}
참조 변수가 일반 객체인 경우
public class Money {
final private Coin coin;
private Money(final Coin coin) {
this.coin = coin;
}
}
참조 변수인 객체도 불변 객체여야 합니다.
public class Coin{
final private int coin;
private Coin(final int coin) {
this.coin = coin;
}
}
배열인 경우
생성자에서 Arrays.copyOf 를 이용하여 저장하고, getter에서 clone을 반환하도록 합니다.
객체로 형성된 배열이라면, 객체 또한 불변 객체여야 합니다.
public class Lotto {
private final int[] lotto;
public Lotto (final int[] lotto) {
this.lotto = Arrays.copyOf(lotto,lotto.length);
}
public int[] getLotto () {
return (lotto == null) ? null : lotto.clone();
}
}
리스트인 경우
생성자에서 새로운 List값을 복사하여 상태를 저장하고,
getter에서 값의 추가와 삭제가 불가능 하도록 Collections.unmodifiableList()를 사용합니다.
객체로 형성된 리스트라면, 객체 또한 불변 객체여야 합니다.
public class Lotto{
private final List<Integer> lotto;
public Lotto(final List<Integer> lotto) {
this.lotto = new ArrayList<>(lotto);
}
public List<Integer> getLotto() {
return Collections.unmodifiableList(lotto);
}
}
"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible.” - Effective Java
참고참고
https://velog.io/@conatuseus/Java-Immutable-Object%EB%B6%88%EB%B3%80%EA%B0%9D%EC%B2%B4
http://www.javapractices.com/topic/TopicAction.do?Id=29
잘봤습니다! 2번 3번의 경우에는 배열, 리스트 그자체는 불변이나 그 안에 있는 요소들까지 불변으로 만들기위해 clone과 collections.unmodifiable을 쓰신건가요?