[김영한의 실전 자바] 중급 1편 - 불변 객체
2024, Nov 07
목차
기본형과 참조형의 공유
기본형(Primitive Type)
- 하나의 값을 여러 변수에서 절대로 공유하지 않는다.
-
//기본형은 절대로 같은 값을 공유하지 않는다. int a = 10; int b = a; // a-> 값 복사 System.out.println("a = " + a); // 10 System.out.println("b = " + b); // 10 b = 20; System.out.println("20 -> b"); System.out.println("a = " + a); // 10 System.out.println("b = " + b); // 20
b = a
라고 하면 자바는 항상 값을 복사해서 대입함
-
참조형(Reference Type)
- 하나의 객체를 참조값을 통해 여러 변수에서 공유할 수 있다.
-
//참조형 변수는 하나의 인스턴스를 공유할 수 있다. Address a = new Address("서울"); Address b = a; System.out.println("a = " + a); // 서울 System.out.println("b = " + b); // 서울 b.setValue("부산"); System.out.println("부산 -> b"); System.out.println("a = " + a); // 부산 System.out.println("b = " + b); // 부산
-
공유 참조와 사이드 이펙트
- 위에서
a = 부산
으로 나오게 된게 사이드 이펙트임
Address a = new Address("서울"); // x001
Address b = new Address("서울"); // x002
- 객체 생성을 따로 해서 아예 주소를 분리하면 해결할 수 있다.
- 여러 변수가 하나의 객체를 공유하는 것을 막을 방법은 없다.
- 그냥 생성부터 다른 객체를 참조하면 됨!
불변 객체 - 도입
- 앞선 문제들의 원인은 객체를 여러 변수에서 공유했기 때문이다.
- 정확히는 공유된 객체의 값을 변경한 것에 있다!
불변 객체 도입
- 불변 객체(Immutable Object) : 객체의 상태(값, 필드, 멤버 변수)가 변하지 않는 객체
- 불변 클래스
-
public class ImmutableAddress { private final String value; public ImmutableAddress(String value) { this.value = value; } public String getValue() { return value; } @Override public String toString() { return "Address{" + "value='" + value + '\'' + '}'; } }
- 필드를
final
로 선언 - setter 를 사용할 수 없음
-
정리
- 불변이라는 단순한 제약을 사용해서 사이드 이펙트를 막을 수 있다.
불변 객체 - 값 변경
값 변경
public static void main(String[] args) {
MutableObj obj = new MutableObj(10);
obj.add(20);
//계산 이후엔 기존 값이 사라짐
System.out.println(obj);
}
public void add(int addValue) {
value+= addValue;
}
- 불변 객체 아닐땐 보통 이렇게 값 변경 할거임
public ImmutableObj add(int addValue) {
return new ImmutableObj(value + addValue);
}
- 이렇게 하면 새로운 객체를 반환하여 불변객체의 값을 변경할 수 있음
[참고] 불변객체를 반환하여 값 변경하고자 할 때 method with~~
로 하는게 관례임
정리
- 자바가 기본으로 제공하는
Integer
,LocalDate
같은 클래스들이 불변으로 설계되어 있다. - 이 외 장점들 : 캐시 안정성, 멀티 쓰레드 안정성, 엔티티 값 타입
- 모든 클래스를 불변으로 만드는 것은 아니다! (값을 변경하면 안되는 특별한 경우에 만들어서 사용)