개요
오늘은 자바에서 자주 사용되는 불변 객체에 대해 정리해보자.
불변 객체
볼변 객체란 한 번 생성되면 그 상태를 변경할 수 없는 객체를 말한다.
즉, 객체의 필드 값을 변경할 수 없으며, 모든 필드는 생성 시 결정되고 이후 수정할 수 없다.
자바에서 대표적인 불변 객체가 String, Boolean, Integer, Long 등이 있다.
보통 참조형 타입의 객체는 모두 불변 객체라고 생각하면 된다.
다음은 참조형 타입의 구현 코드이다.
보다시피 위의 클래스 코드를 보면 클래스 선언부, 멤버 변수 모두 final로 선언되어 있다.
자바에서 불변 객체를 표현하기 위한 키워드는 final이다. 그렇기 때문에 위의 클래스들 모두 불변 객체로 생성되는 것이다.
그렇다고 해서 불변 객체를 아예 변경하기 못하는 것은 아니다.
아래는 String을 변경하는 것 처럼 보이는 재할당 과정이다.
public class ImmutableString {
public static void main(String[] args) {
// 1
String s = "a";
// 2
s = "b";
}
}
1. String s = “a”
2. s = “b”
이렇게 재할당하면 기존의 “a” 를 참조하고 있던 String s 가 새롭게 힙 영역에 생성된 “b” 문자열을 참조하게 되는 것이다.
우리 눈에는 String s 가 “a”에서 “b”로 변경되는 것 같지만, 실제론 재할당되는 것이다.
불변 객체는 변경이 불가능하다. 하지만 재할당은 가능!
다음은 불변이 아닌 클래스의 예시이다.
public class MutableMember {
private String name;
private int age;
public MutableMember(String name, int age) {
this.name = name;
this.age = age;
}
}
위의 클래스를 불변 객체로 사용하기 위해선 다음과 같이 변경해야 한다.
public class ImmutableMember {
private final String name;
private final int age;
public MutableMember(final String name, final int age) {
this.name = name;
this.age = age;
}
}
위처럼 클래스의 각 멤버에 private final 키워드를 붙인다면, 모든 멤버는 클래스 내부에서만 사용 가능하고, 변경도 불가능해진다.
또한 생성자 내부에서 매개변수가 변경되는 것을 방지하기 위해 매개변수에도 final 키워드를 붙였다.
다음은 클래스 내부에 참조형 타입이나 기본형 타입의 멤버가 아닌, 개발자가 직접 생성한 커스텀 클래스인 경우를 추가한 코드이다.
public class Address {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
}
public class ImmutableMember {
private final String name;
private final int age;
private final Address address;
public ImmutableMember(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
}
위의 Address 클래스를 보면 가변 객체가 생성될 것이라는 것을 알 수 있다. (단순히 ImmutableMember.Addess에 final을 붙인다고 불변 객체가 될 수 없다.)
그렇기 때문에 ImmutableMember을 완벽한 불변 객체로 만들기 위해선 멤버 변수도 반드시 불변이어야 한다.
public class Address { // 불변 객체 완성!
private final String city;
private final String street;
public Address(final String city, final String street) {
this.city = city;
this.street = street;
}
}
불변 객체 장점
불변 객체의 장점은 다음과 같다.
Thread-safe
동기화 없이 여러 스레드에서 안전하게 공유 가능하다. 그렇기 때문에 자연스럽게 동시성 문제를 방지할 수 있다.
캐싱 최적화 가능
변경되지 않으므로 메모리에 캐싱하여 사용 가능하다.
불변 객체 단점
불변 객체의 단점은 객체 생성 비용이 증가하는 것이다.
위의 String을 변경하는 예시를 봤듯이, 값이 바뀔 때 마다 기존의 데이터에 작업을 수행하는 것이 아닌, 아예 새롭게 값을 생성한다.
이러한 과정이 반복되면 자연스럽게 메모리 사용량이 증가하게 된다.
'개발 일기' 카테고리의 다른 글
[개발 일기] 2025.01.31 - LSTM (0) | 2025.01.31 |
---|---|
[개발 일기] 2025.01.30 - 객체 지향 생활 체조 9가지 규칙 (1) (0) | 2025.01.30 |
[개발 일기] 2025.01.28 - 이분탐색 (Lower Bound, Upper Bound) (0) | 2025.01.28 |
[개발 일기] 2025.01.27 - Nginx (Feat : Apache Web Server) (0) | 2025.01.27 |
[개발 일기] 2025.01.26 - 논리적 동치성 (Feat : equals()) (1) | 2025.01.26 |