티스토리 뷰
예외가 발생해도 객체가 여전히 정상적으로 사용할 수 있는 상태라면
검사 예외를 던진 경우, 호출자가 오류 상태를 복구할 수 있다.
호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다.
이러한 특성을 실패 원자적(failure-atomic)이라고 하는데,
실패 원자적 특성을 활용하면 작업 도중 예외가 발생해도 그 객체는 여전히 정상적으로 사용할 수 있는 상태이고,
검사 예외를 던진 경우에 호출자가 오류 상태를 복구할 수 있으니 매우 유용하다.
💡 메서드를 실패 원자적으로 만드는 다양한 방법
첫 번째, 불변 객체로 설계한다. (가장 간단한 방법)
불변 객체는 태생적으로 실패 원자적이다.
메서드가 실패하면 새로운 객체가 만들어지지 않을 수 있으나 기존 객체가 불안정한 상태에 빠지는 일은 결코 없다.
불변 객체의 상태는 생성 시점에 고정되어 절대 변하지 않기 때문이다.
두 번째, 작업 수행에 앞서 매개변수의 유효성을 검사한다. (가장 흔한 방법)
객체의 내부 상태를 변경하기 전에 잠재적 예외의 가능성 대부분을 걸러낼 수 있는 방법이다.
public Object pop(){
if(size==0){
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; //다 쓴 참조 해제
return result;
}
또한, 실패할 가능성이 있는 모든 코드를, 객체의 상태를 바꾸는 코드보다 앞에 배치하는 방법도 있다.
세 번째, 객체의 임시 복사본에서 작업을 수행한 다음, 작업이 성공적으로 완료되면 원래 객체와 교체
이 방법은 데이터를 임시 자료구조에 저장해 작업하는 게 더 빠를 때 적용하지 좋다.
ex. 정렬 메서드에서 정렬을 수행하기 전에 입력 리스트의 원소들을 배열로 옮겨 담아 정렬하는 방법
네 번째, 작업 도중 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌리는 방법
주로 디스크 기반의 내구성을 보장해야 하는 자료구조에 쓰이는데, 자주 쓰이는 방법은 아니다.
❓ 항상 실패 원자적으로 만들어야 하나?
일반적으로 권장되는 덕목이지, 항상 그래야 하는 것은 아니다.
실패 원자적으로 만들 수 없는 경우도 있다.
예를 들어, 두 스레드가 동기화 없이 같은 객체를 동시에 수정한다면 그 객체의 일관성이 깨질 수 있다.
따라서 ConcurrentModificationException을 잡아냈다고 해서 그 객체가 여전히 쓸 수 있는 상태라고 가정하면 안 된다.
또한 실패 원자적으로 만들 수 있더라도 항상 그래야 하는 것도 아니다.
실패 원자성을 달성하기 위한 비용이나 복잡도가 아주 큰 연산에서는 그러지 않아도 된다.
그래도 문제가 무엇인지 알고 나면 실패 원자성을 공짜로 얻을 수 있는 경우가 많다.
💡 정리
메서드 명세에 기술한 예외라면 설혹 예외가 발생하더라도 객체의 상태는 메서드 호출 전과 똑같이 유지돼야 한다는 것이 기본 규칙이다.
이 규칙을 지키지 못한다면 실패 시의 객체 상태를 API 설명에 명시해야 한다.
'Programming > Effective Java' 카테고리의 다른 글
[이펙티브자바] Item 77. 예외를 무시하지 말라 (1) | 2022.08.23 |
---|---|
[이펙티브자바] Item 75. 예외의 상세 메시지에 실패 관련 정보를 담으라 (0) | 2022.08.23 |
[이펙티브자바] Item 74. 메서드가 던지는 모든 예외를 문서화하라 (0) | 2022.08.11 |
- Total
- Today
- Yesterday
- 부분집합
- 아이템60
- IMAGE
- 토큰기반인증
- 운영체제
- 그래프탐색
- 아이템61
- dp
- 순열
- subset
- 아이템59
- docker
- bruteforce
- Retrofit2
- 조합
- dfs
- 정처기
- 백준
- Container
- Java
- 알고리즘
- EffectiveJava
- 완탐
- BOJ
- 이펙티브자바
- BFS
- OS
- springboot
- 완전탐색
- docker-compose
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |