티스토리 뷰
- 아이템 69. 예외는 진짜 예외 상황에만 사용하라
- 아이템 70. 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라
- 아이템 71. 필요 없는 검사 예외 사용은 피하라
- 아이템 72. 표준 예외를 사용하라
- 아이템 73. 추상화 수준에 맞는 예외를 던지라
- 아이템 74. 메서드가 던지는 모든 예외를 문서화하라
- 아이템 75. 예외의 상세 메시지에 실패 관련 정보를 담으라
- 아이템 76. 가능한 한 실패 원자적으로 만들라
- 아이템 77. 예외를 무시하지 말라
아이템 69. 예외는 진짜 예외 상황에만 사용하라
- 예외는 오직 예외 상황에서만 써야 하고 절대로 일상적인 제어 흐름용으로 쓰여선 안 된다.
- 특정 상태에서만 호출할 수 있는 '상태 의존적' 메서드를 제공하는 클래스는 '상태 검사' 메서드도 함께 제공해야 한다.
ex) Iterator 인터페이스의 next와 hasNext - 상태 검사 메서드 대신 올바르지 않은 상태일 때 빈 옵셔널 혹은 null 같은 특수한 값을 반환하는 방법도 있다.
- 외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인으로 상태가 변할 수 있다면 옵셔널이나 특정 값을 사용한다.
- 성능이 중요한 상황에서 상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복 수행한다면 옵셔널이나 특정 값을 선택한다.
- 다른 모든 경우엔 상태 검사 메서드 방식이 조금 더 낫다. 가독성이 더 좋기 때문이다.
아이템 70. 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라
- 호출하는 쪽에서 복구하리라 여겨지는 상황이라면 검사 예외를 사용하라.
- 비검사 throwable은 두 가지, 런타임 예외와 에러다. 프로그램에서 비검사 예외나 에러를 던졌다는 것은 복구가 불가능하거나 더 실행해봐야 득보다는 실이 많다는 뜻이다.
- 프로그래밍 오류를 나타낼 때는 런타임 예외를 사용하자.
- 구현하는 비검사 throwable은 모두 RuntimeException의 하위 클래스여야 한다.
- 검사 예외는 일반적으로 복구할 수 있는 조건일 때 발생하므로 호출자가 예외 상황에서 벗어나는 데 필요한 정보를 알려주는 메서드를 함께 제공하는 것이 중요하다.
아이템 71. 필요 없는 검사 예외 사용은 피하라
- 검사 예외가 단 하나뿐이라면 오직 그 예외 때문에 API 사용자는 try 블록을 추가해야 하고 스트림에서 직접 사용하지 못하게 된다. 그러니 이런 상황이라면 검사 예외를 안 던지는 방법이 없는지 고민해볼 가치가 있다.
- 검사 예외를 회피하는 가장 쉬운 방법은 적절한 결과 타입을 담은 옵셔널을 반환하는 것이다.
- 반면, 예외를 사용하면 구체적인 예외 타입과 그 타입이 제공하는 메서드들을 활용해 부가 정보를 제공할 수 있다.
아이템 72. 표준 예외를 사용하라
- 표준 예외를 재사용하면 얻는 게 많다. 그중 최고는 여러분의 API가 다른 사람이 익히고 사용하기 쉬워진다는 것이다.
- 여러분의 API를 사용한 프로그램도 낯선 예외를 사용하지 않게 되어 읽기 쉽게 된다는 장점도 크다.
- 예외 클래스 수가 적을수록 메모리 사용량도 줄고 클래스를 적재하는 시간도 적게 걸린다.
예외 | 주요 쓰임 |
IllegalArgumentException | 허용하지 않는 값이 인수로 건네졌을 때(null은 따로 NullPointerException으로 처리) |
IllegalStateException | 객체가 메서드를 수행하기에 적절하지 않은 상태일 때 |
NullPointerException | null을 허용하지 않는 메서드에 null을 건넸을 때 |
IndexOutOfBoundsException | 인덱스가 범위를 넘어섰을 때 |
ConcurrentModificationException | 허용하지 않는 동시 수정이 발견됐을 때 |
UnsupportedOperationException | 호출한 메서드를 지원하지 않을 때 |
- 인수 값이 무엇이었든 어차피 실패했을 거라면 IllegalStateException을, 그렇지 않으면 IllegalArgumentException을 던지자.
아이템 73. 추상화 수준에 맞는 예외를 던지라
- 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다.
- 예외 연쇄란 문제의 근본 원인인 저수준 예외를 고수준 예외에 실어 보내는 방식이다.
- 고수준 예외의 생성자는 상위 클래스의 생성자에 원인을 건네주어, 최종적으로 Throwable 생성자까지 건네지게 한다.
- Throwable의 initCause 메서드를 이용해 원인을 직접 못박을 수 있다.
- 가능하다면 저수준 메서드가 반드시 성공하도록하여 아래 계층에서는 예외가 발생하지 않도록 하는 것이 최선이다.
아이템 74. 메서드가 던지는 모든 예외를 문서화하라
- 검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 사용하여 정확히 문서화하자. 공통 상위 클래스 하나로 뭉뚱그려 선언하는 일은 삼가자.
- 메서드가 던질 수 있는 예외를 각각 @throws 태그로 문서화하되, 비검사 예외는 메서드 선언의 throws 목록에 넣지 말자. 검사냐 비검사냐에 따라 API 사용자가 해야 할 일이 달라지므로 이 둘을 확실히 구분해주는 게 좋다.
아이템 75. 예외의 상세 메시지에 실패 관련 정보를 담으라
- 실패 순간을 포착하려면 발생한 예외에 관여된 모든 매개변수와 필드의 값을 실패 메시지에 담아야 한다.
- 보안과 관련한 정보는 주의해서 다뤄야 한다. 문제를 진단하고 해결하는 과정에서 스택 추적 정보를 많은 사람이 볼 수 있으므로 상세 메시지에 비밀번호나 암호 키 같은 정보까지 담아서는 안 된다.
- 예외의 상세 메시지와 최종 사용자에게 보여줄 오류 메시지를 혼동해서는 안 된다. 최종 사용자에게는 친절한 안내 메시지를 보여줘야 하는 반면, 예외 메시지는 가독성보다는 담긴 내용이 훨씬 중요하다.
아이템 76. 가능한 한 실패 원자적으로 만들라
- 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다. 이러한 특성을 실패 원자적(failure-atomic)이라고 한다.
- 가장 간단한 방법은 불변 객체로 설계하는 것이다.
- 가변 객체의 메서드를 실패 원자적으로 만드는 가장 흔한 방법은 작업 수행에 앞서 매개변수의 유효성을 검사하는 것이다.
- 실패할 가능성이 있는 모든 코드를, 객체의 상태를 바꾸는 코드보다 앞에 배치하는 방법도 있다.
- 객체의 임시 복사본에서 작업에서 작업을 수행한 다음, 작업이 성공적으로 완료되면 원래 객체와 교체하는 방법도 있다.
- 작업 도중 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌리는 방법도 있다.
아이템 77. 예외를 무시하지 말라
- 예외를 무시하기로 했다면 catch 블록 안에 그렇게 결정한 이유를 주석으로 남기고 예외 변수의 이름도 ignored로 바꿔놓도록 하자.
'공부 > 이펙티브 자바' 카테고리의 다른 글
12장 직렬화 (아이템 85 ~ 90) (0) | 2020.03.30 |
---|---|
11장 동시성 (아이템 78 ~ 84) (0) | 2020.03.24 |
9장 일반적인 프로그래밍 원칙 (아이템 57 ~ 68) (0) | 2020.03.08 |
8장 메서드 (아이템 49 ~ 56) (0) | 2020.03.08 |
이펙티브 자바 스터디 (0) | 2020.03.07 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크