HOWTO · Java

Java의 RuntimeException: 의미, 예제, 검사 예외

Java에서 java.lang.RuntimeException이 무엇을 의미하는지 알아보고, 일반적인 원인을 확인하며, 비검사 런타임 예외와 검사 예외를 비교하세요.

이 페이지의 내용

java.lang.RuntimeException은 Java에서 비검사 예외의 기본 클래스입니다. 컴파일러는 메서드가 이를 포착하거나 throws로 선언할 것을 요구하지 않지만, 복구가 적절한 경우 프로그램이 이를 포착할 수 있습니다. 런타임 예외는 종종 프로그램 로직의 결함이나 성립하지 않은 가정을 가리킵니다.

Java에서 java.lang.RuntimeException 이해하기

런타임 예외는 프로그램이 실행되는 동안 발생할 수 있습니다. 일반적인 예로는 NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException이 있습니다. 이들의 이름은 서로 다른 실패를 설명합니다.

  • NullPointerException은 코드가 null 문자열에 대해 length()를 호출하는 등 null 참조를 역참조할 때 발생할 수 있습니다.
  • ArrayIndexOutOfBoundsException은 코드가 0보다 작거나 배열 길이 이상인 배열 위치를 읽거나 쓸 때 발생할 수 있습니다. 길이가 5인 배열의 경우 유효한 인덱스는 0부터 4까지입니다.
  • ArithmeticException은 정수 나눗셈에서 제수가 0일 때 발생할 수 있습니다. 이 설명은 정수 나눗셈에 관한 것이며, 부동소수점 나눗셈에서 0으로 나누는 경우는 Java에서 다른 규칙을 따릅니다.

이러한 예외는 한 가지 종류의 원인에만 국한되지 않으며, 비검사 예외라고 해서 처리가 불가능한 것은 아닙니다. 먼저 잘못된 상태를 방지할 방법을 찾으세요. 참조를 초기화하고 검증하며, 인덱스는 배열 길이로부터 계산하고, 해당 연산에서 0이 의미가 없는 경우 제수를 검사하세요. 예를 들어 배열 인덱스는 index >= 0 && index < numbers.length일 때 유효합니다.

예제

이 완성된 예제는 각 입력을 사용하기 전에 검증하고 결과 값을 출력합니다.

public class RuntimeExceptionExample {
    public static void main(String[] args) {
        String text = "Java";
        int[] numbers = {10, 20, 30, 40, 50};
        int index = 2;
        int numerator = 12;
        int denominator = 3;

        if (text != null) {
            System.out.println("Text length: " + text.length());
        }

        if (index >= 0 && index < numbers.length) {
            System.out.println("Selected number: " + numbers[index]);
        }

        if (denominator != 0) {
            System.out.println("Quotient: " + numerator / denominator);
        }
    }
}
Text length: 4
Selected number: 30
Quotient: 4

문자열이 존재하고, 선택한 인덱스가 배열 범위 안에 있으며, 제수가 0이 아닙니다. 여기에 설명된 null 역참조, 잘못된 배열 인덱스, 제수 0의 경우는 실행되지 않았습니다. 이러한 실패 중 하나가 발생하면 해당 런타임 예외가 던져집니다. 예외가 포착되지 않으면 그 실행 경로에서 실패한 연산 뒤의 문은 실행되지 않습니다. 각 실패를 시연하려면 입력을 한 번에 하나씩 변경하고 그 경우를 별도로 처리하세요. 포착되지 않는 실패를 여러 개 연속으로 배치하고 각각에 도달할 것으로 기대하지 마세요.

포착은 프로그램에 의미 있는 복구 동작이 있을 때 유용할 수 있지만, 프로그래밍 결함을 숨기기만 하는 광범위한 포착은 진단을 어렵게 만듭니다. 입력은 프로그램에 들어오는 위치 근처에서 검증하고, 예상치 못한 상태의 원인을 수정하는 것을 우선하세요. 테스트와 디버깅은 이러한 결함을 찾는 데 도움이 되며, 코드 분석 도구도 일부 위험한 패턴을 표시할 수 있습니다.

java.lang.RuntimeException과 java.lang.Exception의 차이점

java.lang.RuntimeException은 java.lang.Exception을 확장하므로, 모든 런타임 예외는 예외이기도 합니다. 그러나 java.lang.Exception에는 RuntimeException을 확장하지 않는 검사 하위 클래스도 있습니다. 실질적인 차이는 원인이 외부적인지, 또는 개발자가 이를 포착할 수 있는지가 아니라 컴파일러의 처리 요구 사항에 있습니다.

검사 예외는 포착하거나 메서드의 throws 절에 선언해야 합니다. 예를 들어, 검사 예외를 선언하는 API를 호출하는 코드는 컴파일되려면 그 예외를 고려해야 합니다. NullPointerException과 같은 비검사 예외에 대해서는 Java가 그에 상응하는 포착 또는 선언 요구 사항을 부과하지 않습니다. 검사 예외와 비검사 예외 모두 try와 catch로 포착할 수 있습니다. 런타임 예외를 포착하는 것이 적절한 경우는 코드가 유용하고 명확히 정의된 복구 동작을 수행할 수 있을 때입니다.

Error는 Throwable 아래의 별도 분기이며, Exception의 하위 클래스가 아닙니다. 이 구분은 컴파일러의 검사 예외 규칙이 RuntimeException 하위 클래스와 Error 하위 클래스 이외의 예외 유형에 적용되는 이유를 설명하는 데 도움이 됩니다.

포착되지 않은 예외는 발생한 스레드를 종료시킵니다. 메인 스레드에서 빠져나가면 애플리케이션이 종료될 수 있습니다. 다른 스레드에서 포착되지 않은 예외가 발생했다고 해서 그 자체로 모든 스레드가 중단되어야 한다는 의미는 아닙니다. 처리는 실패에 맞아야 합니다. 프로그램에 건전한 복구 경로가 있는 경우 복구하고, 프로그램을 의도하지 않은 상태로 남겨두는 결함은 수정하세요.

결론

java.lang.RuntimeException은 비검사 예외이므로, 포착할 수는 있지만 Java는 이를 포착하거나 선언할 것을 요구하지 않습니다. null 역참조, 잘못된 배열 인덱스, 정수를 0으로 나누는 경우가 일반적인 예입니다. 가능하면 값을 검증하고 근본적인 결함을 수정하세요. catch 블록은 명확한 복구 동작을 지원할 때 사용하세요. 포착되지 않은 예외는 해당 스레드를 종료시키며, 전체 애플리케이션에 미치는 영향은 어떤 스레드가 실패했는지에 따라 달라진다는 점을 기억하세요.