자바에서 제공하는 예외 클래스다.
exception.getMessage()
를 통해 간단하게 파악할 수 있다.혹여나 자신의 상황에 정확히 맞지 않는 예외가 존재하지 않을 수 있다.
특정 예외 상황만을 걸러내기 어렵다.
→ 상위에서 한 번만 catch
를 한다고 가정하면, 수많은 IllegalArgumentException
중 “이름 입력”에서 발생한 예외만을 골라내 처리하기 어렵다.
예외 클래스의 생성자로 String
만 넘겨줄 수 있다. 다른 객체를 생성자의 매개변수에 넘겨줄 수 없어 구체적인 예외 상황을 알기 어렵다.
자바에서 제공하는 예외를 상속해 직접 만든 예외 클래스다.
클래스의 이름만으로 의미 전달이 가능하다.
커스텀 예외 클래스 내부에서 특별한 후처리가 가능하다.
public class CustomLadderHeightException extends NumberFormatException {
private static final String message = "숫자만 입력 가능합니다.";
public CustomLadderHeightException(String string) {
super(message + "Invalid height : " + string);
// logger.error("!!");
}
}
예외 발생 상황을 개발자가 정확히 알 수 있다.
→ 커스텀 예외이기 때문에, catch
문의 타입으로 사용한다면 구체적인 예외 상황을 정확하게 잡아 처리할 수 있다.
표준 예외가 문자열만을 저장할 수 있는 것과는 달리, 커스텀 예외에는 필요한 객체들을 저장하여 사용할 수 있다. 이를 통해 조금 더 상세한 예외 정보를 제공할 수 있다.
public class IllegalIndexException extends IndexOutOfBoundsException {
private static final String message = "범위를 벗어났습니다.";
public IllegalIndexException(List<?> target, int index) {
super(message + " size: " + target.size() + " index: " + index);
}
}
예외 생성 비용을 줄일 수 있다.
자바는 예외가 발생하면 기본적으로 stack trace를 찍어주기 위한 정보를 생성한다. JVM은 예외 발생 시 call stack에 있는 메서드 리스트를 저장한다. 이를 통해 예외가 발생한 정확한 위치를 파악할 수 있다. 하지만 메서드 리스트를 저장하고 콘솔에 출력하는 데에는 많은 생성 비용이 든다.
예외가 발생하면 비싼 비용을 들여서 stack trace를 생성하는데, 우리가 catch문으로 예외를 잡아 정상 흐름으로 바꾼다면 stack trace를 사용하지 않음에도 불구하고 생성하는 것이고, 이는 성능에 영향을 줄 수 있다.
따라서 Throwable
의 메서드인 fillInStackTrace
를 오버라이딩해 간단하게 출력하거나 출력 자체를 하지 않음으로써 콘솔에 출력하는 생성비용을 줄일 수 있다.
public class IllegalIndexException extends IndexOutOfBoundsException {
...
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
혹은 다음과 같이 Throwable
의 생성자를 사용하면 stack trace를 억제할 수 있다.
// Throwable에서 제공하는 생성자 중 하나
Throwable(
String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace
)
다음과 같이 정의하여 예외를 억제할 수도, 억제하지 않을 수도 있다.
private static class CustomCountInputException extends RuntimeException {
private static final String message = "숫자만 입력 가능합니다.";
private boolean suppressStacktrace = false;
public CustomCountInputException(String message, boolean suppressStacktrace) {
super(message, null, suppressStacktrace, !suppressStacktrace);
}
}
main {
void exceptionHere() {
// throw new IllegalIndexException("NotSuppresed", false);
throw new IllegalIndexException("suppresed", true);
}
}
Java Exception 생성 비용은 비싸다. : NHN Cloud Meetup
Which part of throwing an Exception is expensive?
[Solved] Exception without stack trace in Java