[이펙티브 자바] 아이템 72. 표준 예외를 사용하라

June·2022년 3월 9일
0

[이펙티브자바]

목록 보기
65/72

표준 예외 사용

표준 예외를 사용하라.

  • 많은 프로그래머가 익숙하다. 즉, 가독성이 좋다.
  • 클래스 수가 적으면 메모리 사용량도 줄고 클래스 적재 시간도 적게 걸린다.

적절한 표준 예외 사용

많이 쓰이는 예외

  • IllegalArgumentException: 호출자가 인수로 부적절한 값을 넘길 때 던지는 예외.
  • IllegalStateException: 대상 객체의 상태가 호출된 메서드를 수행하기에 적절하지 않을 때
  • NullPointerException: null 값을 허용하지 않는 메서드에 null을 건낼 때
  • IndexOutOfBoundsException: 시퀀스의 허용 범위 넘을 때
  • ConcurrentModificationException: 단일 스레드에서 사용하려고 설계한 객체를 여러 스레드가 동시에 수정하려고 할 때
  • UnsupportedOperationException: 클라이언트가 요청한 동작을 대상 객체가 지원하지 않을 때
    private Car getMaxPositionCar() {
        return cars.stream()
                .max(Car::compareTo)
                .orElseThrow(() -> new IllegalArgumentException("차량이 존재하지 않습니다"));
       ...
    }

IllegalArgumentException은 어떨 때 사용하는 예외일까요?
-> 인수를 받지 않았으므로 IllegalStateException이 더 적절한 상황이다.

만약 카드 덱을 표현 하는 객체에서 인수로 뽑을 만큼 수를 주는데, 남아 있는 카드 수보다 크다면 어떤 예외?
인수 값이 무엇이든 실패했을 거라면 IllegalStateException, 그렇지 않으면 IllegalArgumentException.

Exception, RuntimeExcpetion, Throwable, Error는 직접 재사용하지 말자. 다른 예외의 상위 클래스이므로 안정적으로 테스트할 수 없다.

직렬화

더 많은 정보를 제공하기를 원한다면 표준 예외를 확장해도 좋은데, 예외는 직렬화 할 수 있다. (12장).
직렬화는 많은 부담이 따르니 이것만으로도 커스텀 예외를 만들지 않을 이유가 된다.

직렬화: 객체를 데이터 스트림으로 만드는 것. 객체를 저장하거나 전송하려면 당연히 해야 한다.
하지만 타입 정보등의 클래스 메타 정보를 포함하기 때문에 성능이 안좋아지고, 역직렬화를 통해 클래스 안의 모든 타입의 객체를 만들어 그 타입 안의 코드 수행 가능해짐. 위험해진다.

IllegalArgumentException -> RuntimeException -> Exception -> Throwable -> Serializable

커스텀 예외 사용

  1. 예외 이름 자체가 정보를 전달할 수 있다.
    NoSuchElementException 보다는 PostNotFoundException이 더 정확하다.

  2. 더 상세하게 예외 정보를 제공할 수 있다.

public class IllegalIndexException extends IndexOutOfBoundsException {
	private static final String message = "범위를 벗어났습니다.";

	public IllegalIndexException(List<?> target, int index) {
		super(message + " size: "  + target.size() + " index: " + index);
	}
}
  1. 예외의 응집도 향상
    예외에 필요한 메시지, 전달할 정보의 데이터 등등을 한 곳에서 관리가 가능하다.

  2. 정확하게 위치 파악이 가능하다.
    커스텀화를 시켰기 때문에 어떤 상황에서 발생했는지 특정할 수 있다.

  3. 예외 생성 비용을 절감한다.
    예외를 생성할 때 stackTrace 때문에 비용이 많이 발생한다. 이 stackTrace는 부모클래스 중 Throwable.fillInStackTrace()에서 발생하는데, 이걸 Override해서 간략하게 하거나 아예 생성하지 않을 수 있다.

참고

테코블 - custom exception을 언제 써야 할까?

0개의 댓글