티스토리 뷰
728x90
반응형
예외는 진짜 예외 상황에만 사용하라
🧨 잘못된 예외의 사용 방법
- 아래의 코드를 보고 무슨 일을 하는 코드인지 가늠하기가 힘듭니다. while 문을 무한으로 순회하면서 range 배열의 각 요소마다 climb() 메서드를 호출하는구나, 배열의 범위 밖의 요소를 찾으면 예외가 발생하고 끝나는구나라고 생각할 수 있습니다.
- 이 코드는 성능 향상,,,?을 위해 작성했다고 생각할 수 있겠지만, 표준 관용구(for-loop)보다 훨씬 느리다고 합니다.
try {
int i = 0;
while(true) {
range[i++].climb();
}
} catch (ArrayIndexOutOfBoundsException e) {
// ...
}
💡 리펙토링
- 아래처럼 사용하면 try-catch문을 사용하지 않아도 됩니다. 왜 위의 예제 코드처럼 사용했을까요? 그 이유는 잘못된 추론을 근거로 성능을 높여보려고 한 것입니다. JVM은 배열에 접근할 때마다 경계를 넘는지 혹은 넘지 않는지 검사하는데, 일반적으로 반복문도 배열 경계에 도달하면 종료합니다. 따라서 try-catch와 반복문을 함께 사용하면 둘 다 경계를 살펴보는 작업을 하게되는데 이는 같은 일이 중복되므로 둘 중 하나는 무시가 됩니다. 아래는 세 가지 부분에서 잘못된 추론입니다.
- 예외는 예외 상황에 쓸 용도로 만들어졌기 때문에 JVM 구현자 입장에서는 빠르게 만들 이유가 없습니다.
- 코드를 try-catch 블록 안에 넣으면 JVM이 적용할 수 있는 최적화가 제한됩니다.
- 배열을 순회하는 표준 관용구(for-loop)는 앞서 중복적인 검사를 수행하지 않습니다. JVM이 알아서 최적화해 없애줍니다.
for (Mountain m : range){
m.climb();
}
💡 예외를 사용하는 원칙
- 예외는 오직 예외 상황에서만 사용해야 합니다. 절대로 일상적인 제어 흐름용으로 사용해서는 안됩니다.
- 이 원칙은 API 설계에도 적용됩니다. 잘 설계된 API라면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야합니다. 특정 상태에서만 호출할 수 있는 "상태 의존적" 메서드를 제공하는 클래스는 "상태 검사" 메서드도 함께 제공해야 합니다.
이와 관련해서는 Iterator 인터페이스의 next(), hasNext() 메서드가 있습니다. 그리고 별도의 상태 검사 덕분에 다음과 같은
for-loop를 사용할 수 있다고 합니다. - 상태 의존적 메서드란 특정 상태에서만 호출할 수 있는 메서드를 의미합니다. (next)
- 상태 검사 메서드란 상태를 검사하는 메서드를 의미합니다. (hasNext)
for (Iterator<Foo> i = collection.iterator(); i.hasNext(); ) {
// loop....
}
💡 상태 검사 메서드, 옵셔널, 특정 값 중 선택하는 지침
- 외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인으로 상태가 변할 수 있다면 옵셔널이나 특정 값을 사용해야 합니다. 상태 검사 메서드와 상태 의존적 메서드를 호출하는 시점에 따라 여러 스레드가 동시에 접근한다면 상태가 변할 수 있기 때문입니다.
- 성능이 중요한 상황에서 상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복해서(동시성) 수행한다면 옵셔널이나 특정 값을 선택해야 합니다.
- 그 외의 경우에는 상태 검사 메서드가 더 낫습니다. 가독성 뿐만 아니라 문제가 발생할 경우 발견하기도 쉬워집니다.
728x90
반응형
'스터디 > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바 - Item71. 필요 없는 검사 예외 사용은 피하라 (0) | 2022.08.20 |
---|---|
이펙티브 자바 - Item70. 복구할 수 있는 상황에는 검사예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 (0) | 2022.08.19 |
이펙티브 자바 - Item66. 네이티브 메서드는 신중히 사용하라 (0) | 2022.08.16 |
이펙티브 자바 - Item64. 객체는 인터페이스를 사용해 참조하라 (0) | 2022.08.16 |
이펙티브 자바 - Item63. 문자열 연결은 느리니 주의하라 (0) | 2022.08.13 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- transactional outbox pattern spring boot
- java ThreadLocal
- 서비스 기반 아키텍처
- spring boot poi excel download
- spring boot redis 대기열 구현
- JDK Dynamic Proxy와 CGLIB의 차이
- 트랜잭셔널 아웃박스 패턴 스프링 부트 예제
- java userThread와 DaemonThread
- 레이어드 아키텍처란
- polling publisher spring boot
- spring boot excel download paging
- space based architecture
- spring boot excel download oom
- redis 대기열 구현
- microkernel architecture
- spring boot redisson sorted set
- redis sorted set으로 대기열 구현
- service based architecture
- redis sorted set
- pipe and filter architecture
- transactional outbox pattern
- pipeline architecture
- 트랜잭셔널 아웃박스 패턴 스프링부트
- 공간 기반 아키텍처
- spring boot redisson destributed lock
- spring boot redisson 분산락 구현
- 람다 표현식
- spring boot 엑셀 다운로드
- 자바 백엔드 개발자 추천 도서
- @ControllerAdvice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함