본문 바로가기

Java/Java 문법

[Java] 예외 처리 (검사형 예외, 비검사형 예외)

728x90
반응형

예외

 

Java에서 모든 예외는 Throwable 클래스를 상속받는다.

 

Throwable 클래스 아래에는 Error 클래스Exception 클래스가 있다.

 

Error는 개발자가 처리할 수 없는 오류를 말하며 Exception은 개발자가 처리할 수 있는 오류를 말한다.

 

Exception은 일반적인 예외와 RuntimeException의 상속을 받는 실행 예외로 나뉜다.

 

 

 

 

 

 

 

 

 

비검사형 예외 (실행 예외)

 

비검사형 예외는 예외 처리를 하지 않아도 컴파일이 가능한 예외이다.

 

대표적인 비검사형 예외

 

예외 발생 이유
ArithmeticException 0으로 나누기와 같은 부적절한 산술 연산의 수행
IllegalArgumentException 메서드에 부적절한 인수를 전달
IndexOutOfBoundsException 범위를 벗어난 인덱스를 사용
NoSuchElementException 요구한 원소가 없음
NullPointerException null 값을 가진 참조 변수에 접근
NumberFormatException 숫자로 바꿀 수 없는 문자열을 숫자로 변환 시도

 

 

 

 

 

 

 

 

검사형 예외 (일반 예외)

 

검사형 예외는 예외 처리를 하지 않으면 컴파일 오류가 발생하는 예외이다.

 

대표적인 일반 예외

 

예외 발생 이유
ClassNotFoundException 존재하지 않는 클래스를 사용하려고 시도
InterruptedException 인터럽트 되었을 때 발생
NoSuchFieldException 클래스가 명시한 필드를 포함하지 않음
NoSuchMethodException 클래스가 명시한 메서드를 포함하지 않음
IOException 입출력 문제가 발생

 

 

 

 

 

 

 

 

예외 처리

 

예외가 발생하면 해당 예외를 담은 오브젝트를 생성하게 된다.

 

해당 예외는 생성한 메서드가 catch 하거나 다른 메서드로 throws 할 수 있다.

 

만약 아무도 예외를 잡지 않으면 RuntimeSystem이 프로그램을 종료시킨다.

 

 

 

 

 

 

 

 

try-catch 문

 

예외를 처리할 때에는 try-catch문을 사용한다.

 

먼저 try 블록 안에서 예외가 발생할 가능성이 있는 코드를 처리한다.

 

이때 만약 예외가 발생하면 catch 블록의 코드가 실행된다.

 

마지막으로 예외 발생 여부와 상관없이 finally 블록의 코드가 실행된다. finally 블록은 필수적이지는 않다.

 

따라서 아래 코드처럼 작성하여 예외 처리를 할 수 있다.

 

try {
    int result = 10 / 0;
    String str = null;
} catch (ArithmeticException | NullPointerException e) {
    System.out.println("예외 발생: " + e.getMessage());
}

 

만약 try 블록 내부에서 예외가 발생하면 그 즉시 catch 블록으로 이동하기 때문에 result는 선언되지 않은 상태가 되며

마찬가지로 str도 선언되지 않는다.

 

 

 

 

 

 

 

 

 

 

다중 catch 문

 

try 블록에서 여러 종류의 예외가 발생할 것으로 예상된다면 이를 각각의 catch 문에서 처리하는 것이 가능하다.

 

다중 catch 문을 사용할 때 항상 서브 클래스가 슈퍼 클래스보다 먼저 와야 한다.

 

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
            String line = reader.readLine();
            System.out.println("Line length: " + line.length()); // NullPointerException 가능성
            reader.close();
        } catch (IOException e) {
            System.out.println("파일을 읽는 중 예외 발생: " + e.getMessage());
        } catch (NullPointerException e) {
            System.out.println("파일 내용이 비어있습니다.");
        }
    }
}

 

 

 

 

Java 7부터는 catch 문이 과도하게 길어지는 것을 방지하기 위해 catch 문에서 OR 연산자의 사용을 허용하고 있다.

 

try {
    BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
    String line = reader.readLine();
    System.out.println("Line length: " + line.length());
    reader.close();
} catch (IOException | NullPointerException e) {
    System.out.println("예외 발생: " + e.getMessage());
}

 

 

 

 

 

 

 

 

 

 

 

예외 출력

 

생성된 예외인 Throwable 객체는 다양한 방법으로 출력이 가능하다.

 

이때 사용할 수 있는 주요 메서드는 아래와 같다.

 

public String getMessage() Throwable 객체의 자세한 메시지를 반환
public String toString() Throwable 객체의 간단한 메시지를 반환
public void printStackTrace() Throwable 객체와 추적 정보를 콘솔 뷰에 출력

 

 

 

 

 

 

 

 

 

throw 문

 

throw 문은 프로그램이 예외를 직접 발생시킬 때 사용한다.

 

public static void main(String[] args) {
    try {
        checkAge(-5); // 유효하지 않은 나이를 전달
    } catch (IllegalArgumentException e) {
        System.out.println("예외 발생: " + e.getMessage());
    }
}

public static void checkAge(int age) {
    if (age < 0) {
        throw new IllegalArgumentException("나이는 음수가 될 수 없습니다."); // 예외 발생
    }
    System.out.println("나이는 " + age + "살입니다.");
}

 

 

 

 

 

 

 

 

 

throws

 

throws 키워드를 사용하면 해당 메서드에서 예외를 직접 처리하지 않고 상위 메서드로 예외를 던질 수 있다.

 

public class Main {
    public static void main(String[] args) {
        try {
            checkAge(-5); // 유효하지 않은 나이를 전달
        } catch (IllegalArgumentException e) {
            System.out.println("예외 발생: " + e.getMessage());
        }
    }

    // checkAge 메서드가 IllegalArgumentException을 던질 수 있음을 선언
    public static void checkAge(int age) throws IllegalArgumentException {
        if (age < 0) {
            throw new IllegalArgumentException("나이는 음수가 될 수 없습니다.");
        }
        System.out.println("나이는 " + age + "살입니다.");
    }
}

 

 

 

 

 

 

 

728x90
반응형