[Java] 예외 처리

artp·2025년 1월 24일

java

목록 보기
14/32
post-thumbnail

9. 예외 처리

예외 처리(Exception Handling)는 프로그램 실행 중 발생할 수 있는 문제를 효과적으로 처리하여, 프로그램의 비정상적인 종료를 방지하고 안정적으로 실행할 수 있도록 돕는 기술입니다.

9.1 오류와 예외

자바 프로그램을 실행하면서 오류(Error)예외(Exception)가 발생할 수 있습니다.
이 두 개념은 프로그램에서 발생하는 문제 상황을 다루는 데 중요한 역할을 합니다.

9.1.1 오류

오류는 프로그램에서 발생할 수 있는 심각한 문제로, 제어할 수 없고, 정상적인 실행도 불가능한 상황을 의미합니다.
프로그램에서 발생하는 오류는 크게 3가지로 나눌 수 있습니다.

오류의 주요 종류

1. 컴파일 타임 오류

  • 컴파일 과정에서 발생하는 오류로, 주로 문법적 문제입니다.
  • 예: 오타, 세미콜론 누락, 잘못된 자료형 사용 등.
int x = "Hello"; // 타입 오류

2. 런타임 오류

  • 실행 중에 발생하는 오류로, 잘못된 연산이나 자원 접근 문제입니다.
  • 예: 0으로 나누기, 없는 파일 접근.

3. 논리 오류

  • 실행은 되지만, 결과가 의도와 다르게 나오는 오류입니다.
  • 예: 잘못된 수식 작성.

9.1.2 예외

예외는 코드 실행 중 발생할 수 있는 예측 가능한 문제로, 개발자가 직접 처리할 수 있습니다.
예외 처리를 통해 프로그램의 안정성을 높이고, 비정상적인 종료를 방지할 수 있습니다.

예외의 분류

1. 확인 예외(checked exception)

확인 예외는 컴파일러가 자바 소스 코드를 컴파일하는 과정에서 예외를 확인하고 예외 처리하는지 검사합니다.
예외 처리하지 않으면 컴파일 오류가 발생하여 컴파일 예외라고도 합니다.

2. 미확인 예외(unchecked exception)

미확인 예외는 컴파일 과정에서 예외 처리를 확인하지 않으며, 명시적으로 예외 처리하도록 강제하지도 않습니다.
런타임에 발생하므로 런타임 예외라고도 합니다.

예외 클래스

자바는 예외를 효과적으로 처리하기 위해 다양한 예외 클래스를 제공합니다.
모든 예외는 최상위 클래스인 Throwable을 기반으로 하며, 두 가지 주요 하위 클래스인 ExceptionError로 나뉩니다.

예외 클래스의 계층 구조

  1. Throwable: 모든 예외와 오류의 최상위 클래스.
  2. Exception: 프로그램에서 예측하고 처리할 수 있는 문제.
    • RuntimeException: 런타임에서 발생하는 예외(미확인 예외).
    • 기타 확인 예외(Checked Exception): 컴파일 시점에서 반드시 처리해야 하는 예외.
  3. Error: 시스템 레벨에서 발생하는 문제로, 개발자가 처리하기 어렵거나 처리가 불가능한 오류.

1. Exception 클래스

Exception 클래스는 코드 실행 중 예측 가능한 문제를 나타냅니다.
잘못된 입력, 파일 입출력 오류, 네트워크 문제 등 주로 프로그램 내부에서 발생하는 문제를 처리합니다.
예외 처리를 강제하는 경우가 많으며, 확인 예외(Checked Exception)에 해당합니다.

주요 예제

  • IOException: 파일 입출력 시 발생하는 예외.
  • ClassNotFoundException: 클래스 로딩 실패.
  • FileNotFoundException: 요청한 파일이 없을 때 발생.

예제: FileNotFoundException 처리

import java.io.*;

public class Main {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("nonexistent.txt");
        } catch (FileNotFoundException e) {
            System.out.println("파일을 찾을 수 없습니다: " + e.getMessage());
        }
    }
}

2. RuntimeException 클래스

RuntimeException 클래스는 실행 시 조건에 따라 발생하는 예외를 나타냅니다.
주로 코드 로직의 문제나 잘못된 사용자 입력으로 인해 발생하며, 미확인 예외(Unchecked Exception)로 분류됩니다.
컴파일러가 예외 처리를 강제하지 않으며, 개발자가 선택적으로 처리합니다.

주요 예제

  • ArithmeticException: 잘못된 산술 연산(예: 0으로 나누기).
  • NullPointerException: null 참조 시 발생.
  • ArrayIndexOutOfBoundsException: 배열의 잘못된 인덱스 접근.
  • IllegalArgumentException: 잘못된 매개변수 전달.
  • NumberFormatException: 숫자 형식 변환 오류.

예제: NullPointerException 처리

public class Main {
    public static void main(String[] args) {
        try {
            String str = null;
            System.out.println(str.length()); // NullPointerException 발생
        } catch (NullPointerException e) {
            System.out.println("예외 발생: " + e.getMessage());
        }
    }
}

3. Error 클래스

Error 클래스는 JVM 환경이나 시스템 수준에서 발생하는 심각한 문제를 나타냅니다.
이러한 오류는 프로그램 외부 요인에 의해 발생하며, 복구가 불가능한 경우가 많습니다.
예외 처리 코드를 작성하기보다는, 일반적으로 프로그램을 종료하는 것이 적합합니다.

주요 예제

  • OutOfMemoryError: 메모리가 부족할 때 발생.
  • StackOverflowError: 무한 재귀 호출로 인해 스택이 초과될 때 발생.
  • VirtualMachineError: JVM 실행 환경 문제.
  • LinkageError: 클래스 로딩 실패.

예제: OutOfMemoryError

public class Main {
    public static void main(String[] args) {
        try {
            int[] largeArray = new int[Integer.MAX_VALUE]; // 메모리 부족
        } catch (OutOfMemoryError e) {
            System.out.println("메모리가 부족합니다: " + e.getMessage());
        }
    }
}

4. 예외 클래스 정리

클래스 종류설명예제
Exception프로그램 내부 문제로 인해 발생하는 예외, 반드시 처리해야 함IOException, ClassNotFoundException
RuntimeException코드 로직 문제로 인해 실행 중 발생하는 예외, 예외 처리 강제하지 않음ArithmeticException, NullPointerException
Error시스템 환경 문제로 인해 발생하는 예외, 복구 불가능OutOfMemoryError, StackOverflowError

9.2 예외 처리하기

자바에서는 예외 처리를 통해 프로그램의 비정상적인 종료를 막고, 안정적으로 실행되도록 합니다.
예외 처리는 try-catch-finally, throw, throws 키워드를 사용하여 구현합니다.

9.2.1 try-catch-finally 문으로 예외 처리하기

  • try 블록: 예외가 발생할 가능성이 있는 코드를 작성합니다.
  • catch 블록: 발생한 예외를 처리합니다.
  • finally 블록: 예외 발생 여부와 상관없이 반드시 실행되는 코드를 작성합니다(선택).

형식

try {
	// 예외가 발생할 가능성이 있는 코드
} catch (예외_클래스 변수명) {
	// 해당 예외가 발생했을 때 수행할 동작
} finally {
	// 예외와 상관없이 항상 실행되는 코드 (선택적)
}

예제

public class Main {
	public static void main(String[] args) {
    	try {
        	int result = 10 / 0; // 예외 발생
            System.out.println(result);
        } catch (ArithmeticException e) {
        	System.out.println("예외 발생: " + e.getMessage());
        } finally {
        	System.out.println("프로그램 종료");
        }
    }
}

출력

예외 발생: / by zero (0으로 나누기를 했을 때 발생한 예외)
프로그램 종료

9.2.2 throw로 예외 발생시키기

코드에 의도적으로 예외를 발생시킬 수도 있습니다. 이럴 때는 throw 키워드를 사용합니다. throw 키워드는 주로 RuntimeException 예외를 처리할 때 사용합니다.

  • throw 키워드는 예외를 명시적으로 발생시킬 때 사용합니다.
  • 개발자가 직접 예외를 발생시키고 이를 처리하도록 강제할 수 있습니다.

형식

new 키워드로 지정한 예외 클래스의 객체를 생성하고 앞에 throw 키워드를 붙여 예외를 발생시킵니다. 이때 예외 메시지를 작성하면 해당 예외 발생 시 해당 메시지가 출력됩니다.

throw new 예외 클래스("예외 메시지");

예제: 나이 검사

public class Main {
	public static void main(String[] args) {
    	try {
        	checkAge(15); // 예외 발생
        } catch (IllegalArgumentException e) {
        	System.out.println("예외 발생: " + e.getMessage());
        }
    }
    
    public static void checkAge(int age) {
    	if (age < 18) {
        	throw new IllegalArgumentException("나이는 18세 이상이어야 합니다.");
        }
    }
}

출력

예외 발생: 나이는 18세 이상이어야 합니다.

9.2.3 throws로 예외 처리 넘기기

throws 키워드는 예외 처리를 다른 곳으로 넘길 때 사용합니다. throws 키워드를 사용하면 해당 메서드에서 예외를 처리하지 않고 호출한 곳에서 처리합니다.

형식

메서드를 선언할 때 시그니처 뒤에 throws 키워드와 메서드에서 발생할 수 있는 예외를 클래스로 명시하면 됩니다. 예외 클래스는 필요한 만큼 throws 뒤에 쉼표로 구분해 나열합니다.

반환형 메서드명(매개변수) throws 예외_클래스 {
	// 수행할 내용
}

예제

import java.io.*;

public class Main {
	public static void main(String[] args) {
    	try {
        	readFile("text.txt"); // 파일 읽기 시도
        } catch (IOException e) {
        	System.out.println("예외 발생: " + e.getMessage());
        }
    }
    
    public static void readFile(String fileName) throws IOException {
    	BufferedReader reader = new BufferedReader(new FileReader(fileName));
        System.out.println(reader.readLine());
        reader.close();
    }
}

출력

예외 발생: text.txt (No such file or directory)
profile
donggyun_ee

0개의 댓글