Java의 오류와 예외처리

곰태우·2025년 9월 17일

Java

목록 보기
1/3
post-thumbnail

이 게시물은 2025-2026 성공회대학교 GDGoC Backend 스터디 세션을 위해 작성되었습니다.

자바에서 발생하는 문제는 크게 두 가지로 나눌 수 있다.

컴파일 오류

프로그램을 실행하기 전, 컴파일 과정에서 발생하는 오류이다.

자바 컴파일러가 소스코드를 바이트코드로 번역하려고 할 때 문법이나 규칙이 어긋나면 발생한다.

ex) 세미콜론(;) 빠짐, 잘못된 자료형 사용 등

컴파일 에러가 있으면 프로그램을 실행조차 할 수 없기 때문에 디버깅이 용이하다. → 상대적으로 좋은 오류이다.

런타임 오류

프로그램이 컴파일에는 성공했지만, 실행 도중 발생하는 오류이다.

코드 문법상 문제는 없지만 실행 환경에서 문제가 생기는 경우 발생한다.

런타임 에러는 실행 도중에야 문제가 드러나기 때문에 재현하기 까다롭고 디버깅이 어렵다.

런타임에 생기는 오류는 에러(Error), 예외(Exception) 2가지로 분류할 수 있다.

에러와 예외

  • 에러(Error) : JVM/시스템 레벨의 심각한 문제로, 코드에서 복구를 기대하기 어렵다. 애플리케이션 개발자는 이 에러를 잡으려고 해서는 안 된다.
  • 예외(Exception) : 프로그램 실행 도중 발생할 수 있는 문제. 상황에 따라 try-catch 또는 throws로 처리할 수 있다.

예외처리

public class Scanner1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("문자열을 입력하세요 :");
        String str = scanner.nextLine(); 
        System.out.println("입력한 문자열: " + str);
        
        System.out.print("정수를 입력하세요 :");
        int intValue = scanner.nextInt(); 
        System.out.println("입력한 정수: " + intValue);
        
        System.out.print("실수를 입력하세요 :");
        double doubleValue = scanner.nextDouble();
        System.out.println("입력한 실수: " + doubleValue);
    }
}
  • 출력 예시
문자열을 입력하세요 : hello
입력한 문자열 : hello
정수를 입력하세요 : 오백
Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:939)
    …

사용자가 정수를 입력해야 하는데 문자열을 입력해 InputMismatchException이 발생했다.
try-catch 문을 이용해 코드를 리팩토링해 보자

  • 리팩토링(Refactoring) : 프로그램의 기능을 변경하지 않으면서 내부 코드 구조를 개선하는 것
public class Scanner1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        try {
            System.out.print("문자열을 입력하세요: ");
            String str = scanner.nextLine();
            System.out.println("입력한 문자열: " + str);

            System.out.print("정수를 입력하세요: ");
            int intValue = scanner.nextInt();
            System.out.println("입력한 정수: " + intValue);

            System.out.print("실수를 입력하세요: ");
            double doubleValue = scanner.nextDouble();
            System.out.println("입력한 실수: " + doubleValue);

        } catch (Exception e) {
            System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
        }
    }
}
  • 출력 예시
문자열을 입력하세요 : 안녕하세요
입력한 문자열 : 안녕하세요
정수를 입력하세요 : 이백
잘못된 입력입니다. 다시 입력해주세요.

예외 계층 구조

상단의 try-catch 문에서 Exception 타입 변수 e를 사용한 것을 보았다.

자바에서 다루는 모든 예외는 Exception 혹은 그 하위 클래스에서 처리한다.

Exception 클래스는 다시 RuntimeException 과 그 외의 자식 클래스 그룹으로 나뉘게 된다.

  • Exception 및 하위 클래스 : 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
    • 존재하지 않는 파일의 이름을 입력 (FileNotFoundException)
    • 입력한 데이터의 형식이 잘못됨 (DataFormatException) 등
  • RuntimeException 클래스 : 프로그래머의 실수로 발생하는 예외
    • 배열의 범위를 벗어남 (IndexOutOfBoundException)
    • null을 참조함 (NullPointerException) 등

Checked Exception / Unchecked Exception

Checked ExceptionUnchecked Exception
처리 여부반드시 예외를 처리해야 함명시적인 처리를 하지 않아도 됨
확인 시점컴파일 단계(실행 불가능)런타임 단계(실행은 가능)
예외 종류FileNotFoundException, DataFormatException 등IndexOutOfBoundsException, NullPointerException 등

두 예외의 핵심적인 차이는 “반드시 예외 처리를 해야 하는가?” 이다.

Checked Exception은 컴파일 단계에서 체크하기 때문에 예외 처리를 하지 않는다면 컴파일이 되지 않는다.

throw - 예외 던지기

try-catch 문을 직역하면, “시도해보고-잡는다” 라는 뜻이다.

잡는 놈이 있으면 던지는 놈도 있지 않을까?

그렇다. 자바는 메서드 안에서 발생한 예외를 나를 호출한 바깥의 메서드에게 던질 수 있다.

throw 예시

public class ThrowExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("결과: " + result);
        } catch (ArithmeticException e) {
            System.out.println("예외가 발생했습니다. 원인: " + e.getMessage());
        }
    }

    public static int divide(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException("0으로 나눌 수 없습니다!");
        }
        return a / b;
    }
}

이와 같이 throw를 이용해 나를 호출한 메서드에게 예외를 던져 호출부에서 예외를 처리하도록 할 수 있다.

이렇게 예외를 다른 곳으로 던지는 것은 코드 가독성, 재사용등, 책임 분배 등의 측면에서 추후에 중요해 진다.

출처

썸네일 이미지 출처 : 블로그 '데블에스 devlog'

profile
막상 해보면 별거 아니다

0개의 댓글