본문 바로가기
Java

자바에서 불변 객체(Immutable Object) 만들기

by 긍고 2024. 9. 25.
728x90
반응형

개요


최근 프로젝트에서 멀티스레드 환경에서 동시성 문제를 해결하는 방법을 고민하던 중, 불변 객체(Immutable Object)를 사용하는 것이 코드 안정성에 큰 도움이 된다는 점을 깨달았다. 여러 스레드가 동일한 객체를 참조할 때, 객체의 상태가 변하지 않으면 추가적인 동기화 처리가 필요 없기 때문이다. 그래서 이번 글에서는 자바에서 불변 객체를 만드는 방법과 그 장점을 소개하려 한다.

 

불변 객체란 무엇인가?


불변 객체란, 한 번 생성된 후 내부 상태가 절대 변경되지 않는 객체를 말한다. 즉, 객체가 생성된 이후에 그 속성들은 수정할 수 없다. 대표적으로 자바의 String 클래스가 불변 객체로 설계되어 있다. 불변 객체는 주로 멀티스레드 환경에서 동시성 문제를 해결하는 데 매우 유용하다.

 

불변 객체의 장점


불변 객체는 여러 장점을 가지고 있다.

  1. 동시성 문제 해결: 불변 객체는 상태가 변경되지 않기 때문에 여러 스레드에서 동시에 사용해도 안전하다. 추가적인 동기화 처리가 필요 없다.
  2. 안정성과 신뢰성: 객체가 변하지 않기 때문에 다른 코드에서 실수로 객체의 상태를 변경할 위험이 없다.
  3. 간편한 테스트: 불변 객체는 테스트가 용이하다. 상태가 변하지 않기 때문에 예상된 값이 항상 동일하게 유지된다.

 

자바에서 불변 객체 만드는 방법


불변 객체를 만들기 위해서는 몇 가지 규칙을 따라야 한다.


모든 필드를 final로 선언하기

필드를 final로 선언하면, 해당 필드는 객체가 초기화될 때 한 번만 값을 설정할 수 있다.

public class ImmutableUser {
    private final String name;
    private final int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

객체 상태를 변경하는 메서드를 제공하지 않기

불변 객체에서는 setter 메서드를 만들지 않는다. 위의 ImmutableUser 클래스는 이름과 나이를 설정한 후 변경할 수 없다.


필드가 참조 타입일 경우, 방어적 복사하기

만약 필드가 참조 타입(예: 배열, 리스트, 객체)이라면, 방어적 복사(defensive copy)를 통해 원본 데이터가 변경되지 않도록 해야 한다.

public 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);  // 방어적 복사
    }
}

위 예제에서 hobbies 리스트를 외부에서 수정할 수 없도록 생성자와 getter 메서드에서 방어적 복사를 적용했다.

 

불변 객체의 사용 사례


불변 객체는 다양한 상황에서 유용하게 쓰인다. 대표적인 사용 사례는 다음과 같다:

  1. 멀티스레드 환경: 불변 객체는 상태가 변하지 않기 때문에 멀티스레드 환경에서 안전하게 사용할 수 있다. 스레드 간에 동기화를 신경 쓸 필요가 없어 성능이 향상된다.
  2. 값 객체(Value Object): 값 객체는 그 자체가 하나의 값으로 사용되며, 주로 식별자(ID)나 좌표, 날짜 등과 같은 개념을 나타낸다. 불변 객체로 설계하면 값 객체의 신뢰성을 높일 수 있다.
  3. 함수형 프로그래밍: 함수형 프로그래밍에서는 상태 변이를 피하는 것이 중요한데, 불변 객체는 이러한 프로그래밍 패러다임에 맞는 데이터 구조이다.

 

정리


불변 객체는 동시성 문제를 해결하고 코드의 안정성을 높이는 데 중요한 역할을 한다. 자바에서 불변 객체를 만드는 방법은 비교적 간단하며, final 필드와 방어적 복사를 활용하면 쉽게 구현할 수 있다. 멀티스레드 환경이나 값 객체를 다룰 때 불변 객체를 사용하는 것은 매우 좋은 선택이다. 불변 객체의 올바른 사용을 통해 더 안전하고 효율적인 코드를 작성할 수 있다.

728x90

댓글