불변 객체
불변 객체
기본형과 참조형의 공유
- 기본형: 하나의 값을 여러 변수에서 절대로 공유하지 않음
- 참조형: 하나의 객체를 참조값을 통해 여러 변수에서 공유 할 수 있음
공유 참조와 사이드이펙트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Address {
private String value;
public Address(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class RefMain1_1 {
public static void main(String[] args) {
//참조형 변수는 하나의 인스턴스를 공유할 수 있다.
Address a = new Address("서울");
Address b = a;
System.out.println("a = " + a);
System.out.println("b = " + b);
b.setValue("부산"); //b의 값을 부산으로 변경해야함
System.out.println("부산 -> b");
System.out.println("a = " + a); // 부산
System.out.println("b = " + b); // 부산
}
}
b만 변경하고 싶었는데 a,b 모두 변경되어 사이드 이펙트가 발생하였습니다.
각각 new Address() 하여 a,b에 넣어줄 수 있지만, 여전히 누군가 변경한다면 사이드 이펙트의 위험이 있습니다.
공유 참조를 막을 방법은 없으니 객체 자체를 불변으로 만들어 사이드이펙트를 방지할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
public class ImmutableAddress {
private final String value;
public ImmutableAddress(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
불변 객체도 값을 변경하고 싶을 때
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ImmutableObj {
private final int value;
public ImmutableObj(int value) {
this.value = value;
}
public ImmutableObj add(int addValue) {
int result = value + addValue;
return new ImmutableObj(result);
}
public int getValue() {
return value;
}
}
이처럼 새로운 불변 객체를 생성하여 반환하도록 하여 값을 수정할 수 있습니다.
보통 setXXX는 내부 값을 변경하는 의도이므로 불변 객체의 변경은 withXXX를 사용하는 것이 관례
불변 클래스가 왜 필요한가?
- 캐시 안정성
- 멀티 쓰레드 안정성
- 엔티티의 값 타입
- 등등
무조건 불변 클래스로 만드는 것이 좋은 것은 아닙니다. 가변 클래스가 더 일반적이며, 값을 변경하면 안되는 특별한 경우에만 사용한다고 생각하면 됩니다.
참고
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.