Java

Java- 불변객체

cinnamonbrown 2026. 3. 11. 23:12

불변객체 (Immutable Object)

불변 객체에 대해 알아보기 전에

먼저 자바의 데이터 타입인 기본형참조형의 차이부터 짚고 넘어가겠습니다


1. 기본형 vs 참조형

1.1 기본형 변수

먼저 기본형 변수는 값 자체를 저장합니다.
예를 들어 int, double, boolean 같은 타입이 기본형에 해당합니다.

// 기본형 변수
int a= 10;
int b=a;
b=100;
System.out.println("a = " + a); // a=10
System.out.println("b = " + b); // b=100

 

실행 결과

a=10 
b=100

왜 이렇게 나올까?

이 코드를 순서대로 보면 다음과 같습니다.

Step1. int a=10;

변수 a에 정수값 10이 저장됩니다.

Step2. int b=a;

변수 b 에 a의 값인 10이 복사되어 저장됩니다.

이 때 중요한 점은 a와 b가 하나의 값을 같이 쓰는 것이 아니라 값이 복사된다는 점입니다.

Step 3. b=100;

이제 b의 값만 100으로 바뀝니다.
이미 a와 b는 각각 별개의 값을 가지고 있으므로, b를 바꿔도 a는 영향을 받지 않습니다.

1.2 참조형 변수

그렇다면 참조형 변수는 어떨까요?

참조형 변수는 값 자체를 저장하는 것이 아니라,

객체의 참조값(주소값) 을 저장합니다.

먼저 다음과 같은 Group 클래스가 있다고 해보겠습니다.

package review.immutable;

public class Group {

    private String name;

    public Group(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

 

이제 이 클래스를 바탕으로 다음 코드를 보겠습니다.

 

Group group1=new Group("Original");
Group group2=group1;

group2.setName("New!");

System.out.println("group1.getName() = " + group1.getName());
System.out.println("group2.getName() = " + group2.getName());

실행 결과

group1.getName() = New!
group2.getName() = New!

왜 둘 다 바뀌었을까?

이것도 순서대로 보면 이해하기 쉽습니다.

 

Step 1. Group group1 = new Group("Original");

"Original"이라는 이름을 가진 Group 객체가 하나 생성되고,group1은 그 객체를 참조하게 됩니다.

 

Step 2. Group group2 = group1;

여기서 group2에 객체가 새로 만들어지는 것이 아닙니다.

group1이 가지고 있던 참조값(주소값) 이 group2에 복사됩니다.
즉, group1과 group2는 서로 같은 객체 하나를 바라보게 됩니다.

 

Step 3. group2.setName("New!");

group2가 참조하는 객체의 name 값을 "New!"로 변경합니다.

그런데 group1도 같은 객체를 참조하고 있으므로,

group1.getName()을 호출해도 바뀐 값인 "New!"가 출력됩니다.

즉, 참조형 변수는 객체를 공유할 수 있기 때문에, 한쪽에서 객체 상태를 변경하면 다른 쪽에도 그 변화가 그대로 반영됩니다.

 

2. 사이드 이펙트(Side Effect)

위의 예시처럼, 어떤 작업이 의도하지 않게 다른 곳에도 영향을 주는 것을 사이드 이펙트라고 합니다.
위 코드에서 group2는 자기 자신의 이름만 바꾸려는 것처럼 보이지만,

실제로는 group1과 같은 객체를 공유하고 있기 때문에 group1의 결과도 함께 바뀌게 됩니다.

Group group1 = new Group("Original");
Group group2 = group1;
group2.setName("New!");

 

원래 이 코드의 의도는 보통 "group2만 바꾸기"일 수 있지만,

실제로는 공유된 객체 자체가 변경되기 때문에 예상하지 못한 결과가 발생할 수 있습니다.

3. 불변 객체 (Immutable Object)

이런 사이드 이펙트를 해결하기 위한 객체가 바로 불변객체입니다.

불변 객체란 객체가 생성된 이후 내부 상태가 바뀌지 않는 객체를 말합니다.
즉, 한 번 만들어진 후에는 값을 수정할 수 없습니다.
대표적인 예시는 다음과 같습니다.

  • String
  • Integer
  • LocalDate

이런 클래스들은 값을 바꾸는 것처럼 보여도,

실제로는 기존 객체를 수정하는 것이 아니라 새로운 객체를 만들어 반환 하는 방식으로 동작합니다.

4. 불변 객체에서 값 변경 방법

그렇다면 불변 객체는 값을 아예 바꿀 수 없는 걸까요?

정확히 말하면 기존 객체의 값은 바꾸지 못하지만,

변경된 값을 가진 새로운 객체를 만들어서 반환할 수는 있습니다.

다음 코드를 보겠습니다.

public class ImmutableObj {

    private final int value;

    public ImmutableObj(int value) {
        this.value = value;
    }

    public ImmutableObj add(int addValue){
        return new ImmutableObj(value+addValue);
    }

    public int getValue() {
        return value;
    }


}
public static void main(String[] args) {
  ImmutableObj obj1=new ImmutableObj(10);
  ImmutableObj obj2=obj1.add(20);

    System.out.println("obj1 = " + obj1.getValue());
    System.out.println("obj2 = " + obj2.getValue());
}

실행결과

obj1 = 10
obj2 = 30

왜 이렇게 될까?

obj1.add(20)을 호출했다고 해서 obj1 자체가 바뀐 것은 아닙니다.

add 메서드는 기존 객체의 값을 변경하지 않고 value + addValue의 결과를 담은. 새로운 객체를 만들어 반환합니다.

따라서

  • obj1는 기존 값 10을 그대로 유지하고
  • obj2는 새롭게 만들어진 객체를 참조해서 30을 가지게 됩니다.

즉, 불변 객체를 사용할 때는

값을 변경하는 것이 아니라,

변경된 결과를 가진 새 객체를 받는 방식으로 이해하면 됩니다.

'Java' 카테고리의 다른 글

래퍼 클래스  (0) 2026.03.20
Java에서 String 비교  (0) 2026.03.16
Object- toString()  (0) 2026.03.03
instanceof  (0) 2026.02.27