Java Exceptions
자바 예외 처리 (Java Exceptions): 개념 및 사용법
자바에서 **예외(Exception)**는 프로그램 실행 중에 발생하는 비정상적인 상황을 의미합니다. 예외 처리는 프로그램의 비정상적인 종료를 방지하고, 오류가 발생했을 때 그에 대한 적절한 대응을 할 수 있도록 도와줍니다. 자바에서는 try-catch 구문을 사용하여 예외를 처리하고, 프로그램의 안정성을 높일 수 있습니다.
1. 자바 예외의 기본 구조
자바의 예외는 크게 두 가지로 나뉩니다:
- Checked Exception (체크 예외): 컴파일 시점에서 반드시 처리해야 하는 예외. 예외 처리 코드가 없으면 컴파일 에러가 발생합니다. 예를 들어,
IOException
,Exception
등이 있습니다. - Unchecked Exception (언체크 예외): 런타임에서 발생하는 예외로, 컴파일러가 예외 처리를 강제하지 않습니다. 주로 프로그래머의 실수로 인해 발생하며,
RuntimeException
을 상속받는 예외들이 여기에 속합니다. 예를 들어,NullPointerException
,ArrayIndexOutOfBoundsException
등이 있습니다.
2. 예외 처리 구문
자바에서 예외를 처리하려면 try-catch
구문을 사용합니다. 예외가 발생할 수 있는 코드를 try
블록에 넣고, 발생한 예외를 catch
블록에서 처리합니다.
기본 구조
try {
// 예외가 발생할 가능성이 있는 코드
} catch (ExceptionType e) {
// 예외 처리 코드
} finally {
// 선택적으로 사용, 항상 실행되는 코드 (예외 발생 여부와 상관없이)
}
예외 처리 예제
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0; // 0으로 나누기 시도 (ArithmeticException 발생)
} catch (ArithmeticException e) {
System.out.println("예외 발생: " + e.getMessage());
} finally {
System.out.println("프로그램 종료.");
}
}
}
출력 예시:
예외 발생: / by zero
프로그램 종료.
try
블록: 예외가 발생할 가능성이 있는 코드를 넣습니다.catch
블록: 발생한 예외를 처리합니다.ExceptionType
은 발생할 수 있는 예외의 타입을 지정하며, 예외 객체e
를 통해 예외 정보를 확인할 수 있습니다.finally
블록: 항상 실행되는 블록으로, 예외가 발생하든 발생하지 않든 무조건 실행됩니다. 주로 자원 해제(예: 파일 닫기, 데이터베이스 연결 해제) 등에 사용됩니다.
3. 자주 발생하는 예외
3.1 ArithmeticException
- *
ArithmeticException
*은 주로 0으로 나누기와 같은 수학적 오류가 발생할 때 던져집니다.
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0; // ArithmeticException 발생
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
}
}
}
3.2 NullPointerException
- *
NullPointerException
*은 널 참조를 사용하려고 할 때 발생합니다. 예를 들어,null
인 객체의 메서드를 호출하려고 할 때 발생합니다.
public class Main {
public static void main(String[] args) {
String str = null;
try {
System.out.println(str.length()); // NullPointerException 발생
} catch (NullPointerException e) {
System.out.println("널 포인터 예외 발생");
}
}
}
3.3 ArrayIndexOutOfBoundsException
- *
ArrayIndexOutOfBoundsException
*은 배열의 잘못된 인덱스에 접근하려고 할 때 발생합니다.
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
try {
System.out.println(numbers[3]); // ArrayIndexOutOfBoundsException 발생
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("잘못된 배열 인덱스 접근");
}
}
}
3.4 NumberFormatException
- *
NumberFormatException
*은 문자열을 숫자로 변환할 때 올바르지 않은 형식의 문자열이 입력되면 발생합니다.
public class Main {
public static void main(String[] args) {
String numberStr = "abc";
try {
int number = Integer.parseInt(numberStr); // NumberFormatException 발생
} catch (NumberFormatException e) {
System.out.println("숫자로 변환할 수 없는 문자열입니다.");
}
}
}
4. 예외 전파 (Throws)
메서드에서 예외가 발생할 수 있음을 호출하는 쪽에 알려주기 위해 throws
키워드를 사용할 수 있습니다. 이는 메서드에서 예외를 처리하지
않고 호출한 쪽으로 예외를 전파하는 방식입니다.
throws
키워드 예제
public class Main {
public static void main(String[] args) {
try {
divide(10, 0); // 0으로 나누기 시도
} catch (ArithmeticException e) {
System.out.println("예외 발생: " + e.getMessage());
}
}
// divide 메서드에서 예외를 전파
public static int divide(int a, int b) throws ArithmeticException {
return a / b;
}
}
출력 예시:
예외 발생: / by zero
위 예제에서는 divide()
메서드에서 예외를 처리하지 않고 throws
키워드를 통해 호출한 쪽으로 예외를
전파했습니다.
5. 사용자 정의 예외 (Custom Exceptions)
자바에서는 사용자 정의 예외를 만들어 프로그램의 특정한 문제를 처리할 수 있습니다. Exception
클래스를 상속받아 사용자 정의 예외를
만들 수 있습니다.
사용자 정의 예외 예제
// 사용자 정의 예외 클래스
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
public class Main {
public static void main(String[] args) {
try {
checkAge(15); // 18세 미만이므로 예외 발생
} catch (InvalidAgeException e) {
System.out.println("예외 발생: " + e.getMessage());
}
}
// 나이를 체크하고 예외를 던짐
public static void checkAge(int age) throws InvalidAgeException {
if (age < 18) {
throw new InvalidAgeException("나이는 18세 이상이어야 합니다.");
}
}
}
출력 예시:
예외 발생: 나이는 18세 이상이어야 합니다.
위 예제에서 InvalidAgeException
이라는 사용자 정의 예외를 만들고, 나이가 18세 미만일 때 해당 예외를 던져 처리했습니다.
6. 다중 예외 처리
try
블록 내에서 여러 예외가 발생할 수 있는 경우, 여러 개의 catch
블록을 사용하여 각각의 예외를 처리할 수
있습니다. 또는 멀티 캐치 구문을 사용하여 한 번에 여러 예외를 처리할 수 있습니다.
다중 catch
예제
public class Main {
public static void main(String[] args) {
try {
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException 발생
int result = 10 / 0; // ArithmeticException 발생
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("잘못된 배열 인덱스 접근");
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
}
}
}
멀티 캐치 예제
public class Main {
public static void main(String[] args) {
try {
int[] numbers = {1, 2, 3};
System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException 발생
int result = 10 / 0; // ArithmeticException 발생
} catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
System.out.println("예외 발생: " + e.getMessage());
}
}
}
출력 예시:
예외 발생: Index 5 out of bounds for length 3
7. finally
블록
finally
블록은 예외 발생 여부와 상관없이 항상 실행되는 코드 블록입니다. 주로
자원 해제(예: 파일, 데이터베이스 연결 해제)와 같은 작업을 처리하는 데 사용됩니다.
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("예외 발생: " + e.getMessage());
} finally {
System.out.println("항상 실행됩니다.");
}
}
}
출력 예시:
예외 발생: / by zero
항상 실행됩니다.
요약
- *예외(Exception)**는 프로그램 실행 중에 발생하는 오류 상황을 나타내며, 자바에서는
try-catch
구문을 통해 예외를 처리합니다. - 예외는 **체크 예외(Checked Exception)**와 **언체크 예외(Unchecked Exception)**로 나뉩니다. 체크 예외는 반드시 처리해야 하고, 언체크 예외는 런타임 시점에서 발생하며 선택적으로 처리할 수 있습니다.
finally
블록은 예외 발생 여부와 상관없이 항상 실행되며, 주로 자원 해제에 사용됩니다.- 자바에서 사용자 정의 예외를 만들어 특정 오류를 처리할 수 있으며,
throws
키워드를 통해 예외를 호출자에게 전파할 수 있습니다.
예외 처리는 프로그램의 안정성을 높이고 오류 발생 시 적절한 대응을 할 수 있도록 도와주는 중요한 기능입니다.