기초 개념
불변객체란 무엇인가?
개념 정의
불변객체(Immutable Object)는 한 번 생성되면 내부 상태가 절대 변하지 않는 객체를 말함
개체가 만들어진 이후에는 속성값을 바꾸거나 수정할 수 없음
반대의 의미로는 Mutable Object(가변 객체)가 있으며 생성된 이후에도 내부 상태를 변경할 수 있는 객체를 말함
예를 들어 ArrayList 같은 클래스는 데이터를 추가하거나 수정할 수 있으므로 mutable한 객체
record
기존 클래스를 Record로 변환하기(JAVA 14+)
전통적인 불변 클래스 → Record 변환
변환 전
public final class Product {
private final String id;
private final String name;
private final BigDecimal price;
public Product(String id, String name, BigDecimal price) {
this.id = id;
this.name = name;
this.price = price;
}
public String getId() { return id; }
public String getName() { return name; }
public BigDecimal getPrice() { return price; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return Objects.equals(id, product.id) &&
Objects.equals(name, product.name) &&
Objects.equals(price, product.price);
}
@Override
public int hashCode() {
return Objects.hash(id, name, price);
}
@Override
public String toString() {
return "Product{id='" + id + "', name='" + name + "', price=" + price + "}";
}
}
변환 후 (Record 사용)
public record Product(String id, String name, BigDecimal price) {
}
Compact Constructor에서 방어적 복사 다루기
왜 Compact Constructor에서 방어적 복사가 중요한가?
: Record도 불변 객체이므로, 가변 컬렉션을 참조할 때는 반드시 방어적 복사가 필요
불변객체의 장점
1. 스레드 안정성 (Thread Safety)
2. 예측 가능성과 신뢰성
3. 캐싱과 최적화
4. HashMap/HashSet의 Key로 안전
5. 방어적 복사 불필요
불변객체의 단점
1. 메모리 오버헤드
2. GC(Garbage Collection) 압박
3. 복잡한 객체 업데이트의 번거로움
4. 성능 민감한 상황에서 부적합
총정리
불변객체 설계 체크리스트
필수 체크사항
- 클래스를 final로 선언
- 모든 필드를 private final로 선언
- equals()와 hashCode() Override
- 생성자에서 모든 필드 초기화
- 가변 객체는 방어적 복사 수행
사용 가이드라인
불변객체가 적합한 경우
- DTO, Value Object
- 설정(Configuration) 객체
- 멀티스레드 환경의 공유 데이터
- Map/Set의 Key
- 캐시 대상 객체
가변객체가 적합한 경우
- 성능이 극도로 중요한 경우
- 빈번하고 복잡한 상태 변경
- 대용량 데이터 처리
- 실시간 처리가 필요한 경우
Best Practice
- 기본적으로 불변으로 설계하기
- 처음부터 불변으로 만들고, 정말 필요할 때만 가변으로 변경
- 나중에 불변으로 바꾸는 것은 매우 어려움
- Java 14+ 환경이라면 Record 적극 활용
- 20줄 코드를 1줄로 줄일 수 있음
- 자동으로 생성자, getter, equals, hashCode, toString 제공
- 컬렉션 필드는 방어적 복사로 보호
- 방어적 복사 : 외부에서 내부 데이터 변경 못하게 복사본 만들기
- 생성자와 getter에서 new ArrayList<>(원본리스트) 사용
'JAVA' 카테고리의 다른 글
| [JAVA] 다형성 파헤쳐보기 (0) | 2025.10.15 |
|---|---|
| [JAVA] 예외처리 (1) | 2025.10.13 |
| [JAVA Algorithm] 컬렉션 프레임워크 (0) | 2025.10.02 |
| [Java Algorithm] 2차원 배열 (0) | 2025.10.02 |
| [JAVA Algorithm] 배열 개념 정리 (0) | 2025.10.01 |