Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Deep Dive
- JWT
- 코딩테스트
- nestjs
- OOP
- 인접행렬
- 인접리스트
- Kubernetes
- javascript
- css
- java
- puppeteer
- Interceptor
- TIL
- dfs
- typescript
- bean
- 자료구조
- 프로그래머스
- Linux
- Spring
- winston
- html
- 탐욕법
- MySQL
- GraphQL
- 알고리즘
- node.js
- REST API
- LifeCycle
Archives
- Today
- Total
처음부터 차근차근
[Java] 불변 객체 본문
728x90
기본형과 참조형의 공유
자바의 데이터 타입을 가장 크게 보면 기본형과 참조형이 있다.
- 기본형 : 하나의 값을 여러 변수에서 절대 공유하지 않는다.
- 참조형 : 하나의 객체를 참조값(주소)을 통해 여러 변수에서 공유할 수 있다.
참조형을 자세히 살펴보면
x라는 객체를 a와 b에서 참조하고 있다.
이때 x의 속성 하나를 변경한다면, a와 b 둘 다 속성이 변하는 것을 알 수 있다.
이는 추가적인 부수 효과를 가져온다.
사이트 이펙트 를 가지고 오는데, 특정 부분에서 발생한 변경이 의도치 않게 다른 부분에 영향을 미치는 경우라고 생각하면 편하다.
이런 경우를 막아야 하는데, 방법으로는
- a와 b가 처음부터 다른 인스턴스를 참조하면 된다.
그러나, 이것은 근본적으로 참조값을 공유하는 방법을 막을 수 없다.
불변 객체
지금까지 발생한 문제를 잘 생각해보면 공유하면 안되는 객체를 여러 변수에서 공유했기 때문에 발생하는 문제이다.
그렇다면, 객체의 상태가 변하지 않는 특별한 객체를 만들면 되지 않을까?
이것을 불변 객체(Immutable Object)라 한다.
package lang.immutable.address;
public class ImmutableAddress {
private final String value;
public ImmutableAddress(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "ImmutableAddress{" +
"value='" + value + '\'' +
'}';
}
}
내부 값이 변경되면 안되기 때문에 final 필드를 선언하였으며, 값을 변경할 수 있는 setValue()를 제거했다.
이 클래스는 생성자를 통해서만 값을 설정할 수 있고, 이후에는 값을 변경하는 것이 불가능하다.
불변이라는 단순한 제약을 사용해서 사이드 이펙트라는 큰 문제를 막을 수 있다.
- 객체의 공유 참조는 막을 수 없다. 그래서 객체의 값을 변경하면 다른 곳에서 참조하는 변수의 값도 함께 변경되는 사이드 이펙트가 발생한다. 사이드 이펙트가 발생하면 안되는 상황이라면 불변 객체를 만들어서 사용하면 된다. 불변 객체는 값을 변경할 수 없기 때문에 사이드 이펙트가 원천 차단된다.
- 불변 객체는 값을 변경할 수 없다. 따라서 불변 객체의 값을 변경하고 싶다면 변경하고 싶은 값으로 새로운 불변 객체를 생성해야 한다. 이렇게 하면 기존 변수들이 참조하는 값에는 영향을 주지 않는다.
불변 객체의 값을 변경하고 싶다면??
불변 객체를 사용하지만 그래도 값을 변경해야 하는 메서드가 필요하면 어떻게 해야할까? (참고로 불변 객체는 변하지 않아야 한다.)
package lang.immutable.change;
public class ImmutableObj {
private final int value;
public ImmutableObj(int value) {
this.value = value;
}
public ImmutableObj add(int addValue) {
int result = value + addValue;
return new ImmutableObj(result);
}
public int getValue() {
return value;
}
}
불변 객체는 값을 변경하면 안된다. 그러면 이미 불변 객체가 아니다.
따라서 기존값을 변경하지 않고, 계산 결과를 바탕으로 새로운 객체를 만들어서 반환한다.
이렇게 하면 불변도 유지하면서 새로운 결과를 만들 수 있다.
참조
'Language > Java' 카테고리의 다른 글
[Java] Wrapper Class (0) | 2024.07.31 |
---|---|
[Java] String 클래스 (0) | 2024.07.31 |
[Java] Object 클래스 (0) | 2024.07.24 |
[Java] Interface (1) | 2024.01.02 |
[Java] abstract 추상 클래스 & 추상 메서드 (1) | 2024.01.02 |