정의

- 생성 후 그 상태를 변경할 수 없는 객체를 의미함
- 불변 객체는 프로그램의 안정성을 높이고 예측 가능한 코드를 작성하는 데 도움이 됨
- 특히, 멀티스레드 환경에서는 동시 접근 시 상태 변화가 없어 안전하게 사용할 수 있어 유용함

예시

자바에서 불변 객체를 만드는 대표적인 방법은 final 키워드를 사용하는 것
String 클래스가 대표적인 불변 클래스임
public final class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter만 제공, Setter는 제공하지 않음
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}​

 

자바에서 많이 쓰이는 불변 클래스들은 다음과 같음

클래스 설명
String 문자열의 내용을 변경할 수 없기 때문에, 새로운 문자열이 생성될 때마다 새로운 객체가 만들어짐
Wrapper 클래스 Integer, Double, Boolean 등 자바의 기본 타입을 감싸는 클래스들은 모두 불변 객체
LocalDate, LocalDateTime Java에서 날짜와 시간 API의 대부분 객체는 불변 객체로 설계되어 있어 안정성이 높음

특징과 장점, 주의점

1. 특징

1. 초기화 후 상태 변경 불가
- 객체가 생성된 이후에는 내부 상태가 절대 바뀌지 않음

2. 방어적 복사
- 객체 생성 시 전달받은 객체의 방어적 복사(defensive copy)를 통해 외부에서 객체 상태를 바꿀 수 없게 함

3. 쓰레드 안정성(Thread-Safe)
- 상태가 변하지 않으므로 동기화 없이 여러 스레드에서 안전하게 접근할 수 있음
2. 장점

1. 동시성 문제 해결
- 불변 객체는 스레드 간 공유에 있어 동기화 없이 안전하게 사용할 수 있어 동시성 문제가 줄어듦

2. 안정성
객체의 상태가 변경되지 않아 예측 가능한 동작을 수행

3. 의도 명확성
상태가 변하지 않기 때문에 코드를 읽을 때 그 의도를 명확하게 파악할 수 있음
3. 주의점

- 불변 객체는 많은 장점이 있지만 불필요한 객체 생성이 발생할 수 있음
- 값이 자주 바뀌어야 하는 경우라면 가변 객체를 사용하는 것이 성능에 더 유리할 수 있음
👉  불변 객체를 사용할지, 가변 객체를 사용할지 상황에 맞게 선택하는 것이 중요함

생성법

1. 클래스를 final로 선언하여 상속을 막음
2. 모든 필드를 final로 선언하여 값 변경을 방지
3. Setter 메서드를 제공하지 않음으로써 외부에서 필드 값을 수정할 수 없게 함
4. 방어적 복사
- 만약 필드가 객체 참조를 포함하는 경우, 해당 객체를 복사하여 반환함으로써 외부에서 객체의 상태를 변경하지 못하도록 함

예를 들어, 필드가 List일 경우 방어적 복사를 구현할 수 있음
public final class ImmutablePerson {
    private final String name;
    private final List<String> hobbies;

    public ImmutablePerson(String name, List<String> hobbies) {
        this.name = name;
        this.hobbies = new ArrayList<>(hobbies); // 방어적 복사
    }

    public String getName() {
        return name;
    }

    public List<String> getHobbies() {
        return new ArrayList<>(hobbies); // 방어적 복사
    }
}​

비고

1. 불변 객체 관련 복사 방지 예외 때문에 찾아보면서 정리가 많이 되었다.

레퍼런스

1. 멘토링 강의
2. 구글링, 코드 예시의 경우 ChatGPT

 

'개발지식 조각 > Java' 카테고리의 다른 글

런타임 예외와 Unchecked Exception  (0) 2024.10.31
추상클래스와 메서드  (0) 2024.10.31
함수와 메서드의 차이  (0) 2024.10.25
[Java] IllegalArgumentException  (0) 2024.10.23
오버라이딩(Overriding)  (0) 2024.10.23

+ Recent posts