코드를 재사용하는 이점은 예외에도 똑같이 적용된다. 표준 예외를 재사용하면 많은 이득을 얻을 수 있다.
- API를 만들 때, 다른 사람이 익히고 사용하기 쉬워진다. (익숙해진 규약을 따르기 때문에)
- 낯선 예외를 사용하지 않으면, 코드를 읽기 쉬워진다.
- 예외 클래스 수가 적을수록 메모리 사용량이 줄고, 클래스를 적재하는 시간도 적게 걸린다.
IllegalArgumentException: 호출자가 인수에 부적절한 값을 넘길 때 던짐IllegalStateException: 대상 객체의 상태가 호출된 메서드를 수행하기 적합하지 않을 때 던짐NullPointerException:null허용하지 않는 메서드에null넘길 때 던짐IndexOutOfBoundsException: 어떤 시퀀스의 허용 범위를 넘는 값을 건넬 때ConcurrentModificationException: 단일 스레드에서 사용하려고 설계한 객체를 여러 스레드가 동시 접근하여 수정하려고 할 때 던짐UnsupportedOperationException: 클라이언트가 요청한 동작을 대상 객체가 지원하지 않을 때 던짐- 보통 잘 사용하지는 않는데, impl 한 특정 인터페이스의 메서드를 지원하지 않을 때 던진다.
- ex. 읽기 전용
List를 만들었는데, 여기서remove()를 호출하려고 할 때 던질 수 있다.
이 클래스들은 추상 클래스라고 생각하자. 이 예외들은 다른 예외들의 상위 클래스이므로 안정적으로 테스트 할 수 없다.
직접 재사용하는 것 == 구체적인 상황 설명 없이 제네릭 예외를 그대로 throw 하는 행위이다. 이는 상황 표현이 모호하다는 문제점과, 잘못된 후속 처리 유발 등의 위험성이 있어 기피된다.
- 구체적인 정보를 제공하고 싶을 때, extends 하여 (표준) 예외를 확장할 수 있다.
- 그러나, 예외는 직렬화 가능하므로 주의하자.
- 직렬화에는 많은 부담이 따른다.
- 특히, 예외 객체는 단순한 메시지만 담고 있지 않고, Stack Trace 정보를 가진다. 이 거대한 객체를 바이트 스트림으로 변환하는 직렬화 비용은 상당히 크기 때문에 직렬화하지 말자.
- 또한, 직렬화된 예외 객체가 외부에 노출되면 시스템의 내부 정보까지 노출된다.
- 커스텀 예외는 해당 예외가 충분하고 이점이 있는 정보를 제공할 때 사용하자. (남용 금지)
- 인수 값이 무엇이든 어차피 실패했을 것이라면?
IllegalStateException - 인수 값에 따라 달라지면?
IllegalArgumentException