불변객체 (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 |