Immutable 객체
Immutable 객체
개요
Immutable 객체(불변 객체)는 객체지향프로그래밍(OOP)에서 중요한 개념 중 하나로, 객체가 생성된 이후 그 내부 상태를 변경할 수 없는 객체를 의미합니다. 즉, Immutable 객체는 초기화된 후 어떤 메서드도 내부 데이터를 수정하지 않으며, 상태 변경이 필요한 경우 기존 객체를 수정하는 대신 새로운 객체를 생성하여 반환합니다. 이는 프로그램의 안정성, 스레드 안정성(thread safety), 디버깅 용이성, 그리고 함수형 프로그래밍과의 호환성 측면에서 큰 장점을 제공합니다.
Immutable 객체는 Java, Python, C#, Kotlin 등 다양한 객체지향 언어에서 활용되며, 특히 동시성 프로그래밍(concurrent programming)과 함수형 프로그래밍 패러다임에서 핵심적인 역할을 합니다.
Immutable 객체의 특징
Immutable 객체는 다음과 같은 주요 특징을 가집니다:
- 상태 변경 불가: 객체 생성 후 필드 값이 변경되지 않음.
- 스레드 안전성: 공유 데이터가 변경되지 않기 때문에 멀티스레드 환경에서 안전하게 사용 가능.
- 해시 기반 컬렉션에 적합: 해시 값이 변하지 않아
[HashMap](/doc/%EA%B8%B0%EC%88%A0/%EC%9E%90%EB%B0%94/%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC/HashMap)
,[HashSet](/doc/%EA%B8%B0%EC%88%A0/%EC%9E%90%EB%B0%94/%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC/HashSet)
등에 안전하게 사용 가능. - 캐싱 및 재사용 용이: 동일한 상태의 객체는 캐싱하여 재사용할 수 있음.
- 예측 가능한 동작: 객체의 상태가 변하지 않기 때문에 디버깅과 테스트가 쉬움.
Immutable 객체의 예시
Java에서의 Immutable 객체
Java에서는 [String](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%90%EB%A3%8C%ED%98%95/String)
, [Integer](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%90%EB%A3%8C%ED%98%95/Integer)
, [LocalDateTime](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%90%EB%A3%8C%ED%98%95/LocalDateTime)
등이 대표적인 Immutable 클래스입니다.
String str = "Hello";
str = str.concat(" World"); // 새로운 String 객체를 생성
위 코드에서 concat()
메서드는 기존 str
객체를 수정하지 않고, "Hello World"
를 담은 새로운 String 객체를 반환합니다. 이는 String
클래스가 내부적으로 final
필드를 사용하고, 모든 상태 변경 메서드가 새로운 인스턴스를 반환하도록 설계되어 있기 때문입니다.
사용자 정의 Immutable 클래스를 작성하는 예시:
public final class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
// 상태 변경이 필요한 경우 새로운 객체 생성
public Person withAge(int newAge) {
return new Person(this.name, newAge);
}
}
final class
: 상속 불가능하게 하여 하위 클래스에서 상태를 변경하는 것을 방지.private final
필드: 내부 상태 변경 불가.- 게터만 제공, 세터 미제공.
- 상태 변경이 필요한 경우
withAge()
처럼 새로운 객체를 반환하는 메서드 제공 (Fluent API 스타일).
Immutable 객체의 장점
장점 | 설명 |
---|---|
스레드 안전성 | 객체가 변경되지 않기 때문에 여러 스레드가 동시에 접근해도 데이터 경합(race condition) 발생하지 않음. |
예측 가능한 상태 | 객체의 상태가 생성 후 변하지 않아, 디버깅과 테스트가 용이함. |
캐싱 및 재사용 | 동일한 값을 가진 객체는 캐싱하여 메모리 사용을 최적화할 수 있음 (예: String Pool). |
함수형 프로그래밍과의 호환성 | 순수 함수(pure function)와 잘 어울림. 상태 부작용(side effect) 없음. |
컬렉션의 키로 사용 가능 | 해시 값이 변하지 않으므로 HashMap 의 키로 안전하게 사용 가능. |
Immutable 객체의 단점
- 성능 오버헤드: 상태 변경 시마다 새로운 객체를 생성하므로, 빈번한 변경이 발생하면 메모리 사용량과 GC(Garbage Collection) 부담이 증가할 수 있음.
- 복잡한 객체 구조에서는 불편: 내부에 컬렉션을 포함하는 경우, 해당 컬렉션도 불변으로 관리해야 함.
- 일부 언어에서는 지원 부족: 모든 언어가 Immutable 객체를 쉽게 만들 수 있는 기능을 제공하지는 않음.
Immutable 객체와 Mutable 객체 비교
구분 | Immutable 객체 | Mutable 객체 |
---|---|---|
상태 변경 | 불가능 | 가능 |
스레드 안전성 | 높음 | 낮음 (동기화 필요) |
메모리 사용 | 변경 시 새 객체 생성 → 더 큼 | 기존 객체 재사용 → 작음 |
사용 예시 | String , LocalDateTime |
[StringBuilder](/doc/%EA%B8%B0%EC%88%A0/%EC%9E%90%EB%B0%94/%EB%AC%B8%EC%9E%90%EC%97%B4%20%EC%B2%98%EB%A6%AC/StringBuilder) , [ArrayList](/doc/%EA%B8%B0%EC%88%A0/%EC%9E%90%EB%B0%94/%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC/ArrayList) |
언어별 Immutable 객체 지원
- Java:
final
키워드, 불변 클래스 설계,[Collections.unmodifiableList](/doc/%EA%B8%B0%EC%88%A0/%EC%9E%90%EB%B0%94/%EC%BB%AC%EB%A0%89%EC%85%98%20%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC/Collections.unmodifiableList)()
등 제공. - Python:
[tuple](/doc/%EA%B8%B0%EC%88%A0/%ED%8C%8C%EC%9D%B4%EC%8D%AC/%EC%9E%90%EB%A3%8C%ED%98%95/tuple)
,[frozenset](/doc/%EA%B8%B0%EC%88%A0/%ED%8C%8C%EC%9D%B4%EC%8D%AC/%EC%9E%90%EB%A3%8C%ED%98%95/frozenset)
,str
은 불변. 사용자 정의 클래스는[__slots__](/doc/%EA%B8%B0%EC%88%A0/%ED%8C%8C%EC%9D%B4%EC%8D%AC/%ED%81%B4%EB%9E%98%EC%8A%A4%20%EC%B5%9C%EC%A0%81%ED%99%94/__slots__)
와 프로퍼티로 제어 가능. - C#:
[readonly](/doc/%EA%B8%B0%EC%88%A0/C%23/%EB%B6%88%EB%B3%80%EC%84%B1/readonly)
,record
타입(특히record struct
)을 통해 불변성 지원. - Kotlin:
[val](/doc/%EA%B8%B0%EC%88%A0/%EC%BD%94%ED%8B%80%EB%A6%B0/%EB%B3%80%EC%88%98%20%EC%84%A0%EC%96%B8/val)
선언,[data class](/doc/%EA%B8%B0%EC%88%A0/%EC%BD%94%ED%8B%80%EB%A6%B0/%ED%81%B4%EB%9E%98%EC%8A%A4%20%EC%84%A4%EA%B3%84/data%20class)
와 함께 불변성 강조.
참고 자료 및 관련 문서
- Oracle Java Documentation - Immutable Objects
- Joshua Bloch, 『Effective Java』, Item 17: "Minimize mutability"
- MDN Web Docs - Immutable data structures
- 함수형 프로그래밍, 불변성(Immutability), 스레드 안전성(Thread Safety), final 키워드
Immutable 객체는 현대 소프트웨어 개발에서 안정성과 유지보수성을 높이는 핵심 개념입니다. 특히 대규모 시스템이나 동시성 환경에서는 반드시 고려해야 할 설계 원칙 중 하나입니다. 객체의 상태를 변경하지 않고 새로운 객체를 생성함으로써, 예기치 않은 부작용을 방지하고 코드의 명확성을 높일 수 있습니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.