예외
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 + "살입니다.");
}
}
'Java > Java 문법' 카테고리의 다른 글
[Java] 레이스 컨디션 (Race Condition), 스레드 동기화 (synchronized) (0) | 2024.12.01 |
---|---|
[Java] 스레드(Thread), 모니터(Monitor), Runnable 인터페이스 (0) | 2024.10.27 |
[Java] Iterator 인터페이스 (0) | 2024.10.14 |
[Java] 컬렉션 프레임워크 (Collection Framework), List 인터페이스 (List interface) (0) | 2024.10.14 |
[Java] package, import (0) | 2024.10.11 |