예외와 에러
프로그래밍에서 예외(Exception)란 입력 값의 처리가 불가능하거나 참조된 값이 잘못된 경우 등 애플리케이션이 정상적으로 동작하지 못하는 상황을 의미합니다. 예외는 개발자가 직접 처리할 수 있으므로 미리 코드 설계를 통해 처리할 수 있습니다.
에러(Error)란 예외와 비슷한 의미지만 엄연히 다른 용어로, 에러는 주로 자바의 가상머신(JVM)에서 발생시킵니다.
따라서 예외와 달리 애플리케이션에서 처리할 수 있는 것이 없습니다.
대표적인 예로 메모리 부족(OutOfMemory
), 스택 오버플로(StackOverFlow
)가 있습니다. 이러한 에러는 발생 시점에 처리하는 것이 아니라 미리 애플리케이션의 코드를 살펴보면서 문제가 발생하지 않도록 예방해서 원천적으로 차단해야 합니다.
예외 클래스
자바에서 모든 예외 클래스는 Throwable
클래스를 상속받습니다. Exception
클래스는 크게 Checked Exception
, UncheckedException
이 있습니다. 위에서 파란 점선 내부에 있는 Exception이 Checked Exception, 주황색 점선 내부에 있는 Exception이 UncheckedException 입니다.
Checked Exception
은 컴파일 단계에서 확인 가능한 예외 상황입니다. 이러한 예외는 IDE에서 캐치해서 반드시 예외 처리를 할 수 있게 표시해줍니다.
반면 Unchecked Exception
은 런타임 단계에서 확인되는 예외 상황을 나타냅니다. 즉, 문법상 문제는 없지만 프로그램이 동작하는 도중 예기치 않은 상황이 생겨 발생하는 예외를 의미합니다.RuntimeException
을 상속받는 Exception
클래스는 Unchecked Exception
이고 그렇지 않은 Exception
클래스는 Checked Exception
입니다.
예외 처리 방법
예외가 발생했을 때 이를 처리하는 방법은 크게 세 가지가 있습니다.
- 예외 복구
- 예외 처리 회피
- 예외 전환
예외 복구
예외 복구 방법은 예외 상황을 파악해서 문제를 해결하는 방법입니다. 대표적인 방법이 try/catch
구문입니다. try
블록에는 예외가 발생할 수 있는 코드를 작성합니다. 그리고 catch
블록을 거치면서 예외 유형과 매칭되는 블록을 찾아 예외 처리 동작을 수행합니다.
public class UserInputExample {
public static void main(String[] args) {
String userInput = "123abc"; // Simulate user input that might not be a number
try {
int age = Integer.parseInt(userInput); // Attempt conversion
System.out.println("Your age is: " + age);
} catch (NumberFormatException e) {
System.err.println("Error: Invalid age format. Please enter a number.");
}
}
}
예외 처리 회피
이 방법은 예외가 발생한 시점에서 바로 처리하는 것이 아니라 예외가 발생한 메서드를 호출한 곳에서 에러 처리를 할 수 있게 전가하는 방식입니다. 이때 throw
키워드를 사용해 어떤 예외가 발생했는지 호출부에 내용을 전달할 수 있습니다.
public class ValidateAge {
public static void checkAge(int age) throws InvalidAgeException {
if (age < 0) {
throw new InvalidAgeException("Age cannot be negative!");
}
System.out.println("Your age is valid.");
}
public static void main(String[] args) {
try {
checkAge(-5); // This will throw an InvalidAgeException
} catch (InvalidAgeException e) {
System.err.println(e.getMessage());
}
}
}
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message); // Call superclass constructor to set the message
}
}
예외 전환
이 방법은 앞의 두 방식을 적절하게 섞은 방식입니다. 예외가 발생했을 때 어떤 예외가 발생했느냐에 따라 호출부로 예외 내용을 전달하면서 좀 더 적합한 예외 타입으로 전달할 필요가 있습니다. 또는 애플리케이션에서 예외 처리를 좀 더 단순하게 하기 위해 래핑(wrapping)해야 하는 경우도 있습니다. 이런 경우에는 try/catch
방식을 사용하면서 catch
블록에서 throw
키워드를 사용해 다른 예외 타입으로 전달하면 됩니다.
참고
- 스프링 부트 핵심 가이드 "스프링 부트를 활용한 애플리케이션 개발 실무" , 장정우, 2022
'ComputerScience > Java' 카테고리의 다른 글
[Java] Compile Time과 Runtime의 차이 (1) | 2024.03.08 |
---|---|
[Java] Logback - 로깅 라이브러리 (0) | 2024.02.22 |
[Java] immutable(불변) 객체란? (0) | 2024.02.22 |
[Java] JUnit5 (0) | 2024.02.22 |
[Java] Java에서 Queue와 구현체들 (+ ArrayList와 LinkedList의 차이) (0) | 2024.01.31 |