프로그램에서 예외가 발생한 경우, 프로그램의 갑작스러운 종료를 막고 정상 실행을 유지할 수 있도록 처리하는
코드를 예외 처리 코드라고 한다.
자바 컴파일러는 소스 파일을 컴파일 할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면,
컴파일 오류를 발생시켜서 개발자가 강제적으로 예외 처리 코드를 작성하도록 요구한다.
하지만 실행 예외는 컴파일러가 체크하지 않기 때문에, 개발자의 경험을 바탕으로 작성해야 한다.
예외 처리 코드는 try - catch - finally 블록을 이용한다.
try - catch - finally 블록은 생성자 내부와 메소드 내부에서 작성되어
일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있게 한다.
try 블록에는 예외 발생 가능성이 있는 코드가 위치한다.
try 블록에서 예외가 발생하지 않고 정상적으로 실행되면, catch 블록은 실행되지 않고
finally 블록의 코드를 실행한다.
만약 try 블록에서 예외가 발생하면, 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행한다.
이후 finally 블록의 코드를 실행한다.
- finally : 예외 발생 여부와 상관 없이 항상 실행할 내용
- try, catch 블록에서 return 문을 사용하더라도 finally 블록은 항상 실행된다.
예를 들어 Class.forName() 메소드는 매개 값으로 주어진 클래스가 존재하면 Class 객체를 리턴하지만,
존재하지 않으면 ClassNotFoundException 예외를 발생시킨다.
ClassNotFoundException 예외는 일반 예외이므로 컴파일러는 개발자로 하여금
예외 처리 코드를 작성하도록 요구한다.
ex)TryCatchFinallyExam.java : 일반 예외 처리
public class TryCatchFinallyExam {
public static void main(String[] args) {
try {
Class clazz = Class.forName("java.lang.String2"); // 예외 발생!!
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다..");
}
}
}
forName( ) 메소드의 매개 값으로 주어진 java.lang.String2 클래스는 존재하지 않아서 예외가 발생하게 된다.
따라서 catch 블록을 수행하여 예외 처리를 하게 된다.
단, ArrayIndexOutOfBoundsExceptionm, NumberFormatException 같은 실행 예외는
컴파일러가 예외 처리 코드를 체크하지 않기 때문에 개발자 경험에 의해 에러 코드를 아래와 같이 작성해야 한다.
ex)TryCatchFinallyRuntimeExceptionExam.java : 실행 예외 처리
public class TryCatchFinallyRuntimeExceptionExam {
public static void main(String[] args) {
String data1 = null;
String data2 = null;
try {
data1 = args[0]; // 예외 발생! ArrayIndexOutOfBoundsException
data2 = args[1];
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개 값의 수가 부족합니다.");
System.out.println("[실행 방법]");
System.out.println("java TryCatchFinallyRuntimeExceptionExam num1 num2");
return;
}
try {
int value1 = Integer.parseInt(data1); // 숫자가 아닐 경우에 예외 발생 null 이므로 발생!
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
}
}
1. 다중 catch 문
try 블록 내부에는 다양한 종류의 예외가 발생할 수 있다.
발생되는 예외에 따라 예외 처리 코드를 다르게 지정하려면 다중 catch 문을 사용해야 한다.
catch 블록의 예외 클래스 타입은 try 블록에서 발생된 예외 종류를 말하며,
try 블록에서 해당 타입의 예외가 발생하면 catch 블록을 실행한다.
try {
ArrayIndexOutOfBoundsException 발생!!
NumberFormatException 발생!!
} catch(ArrayIndexOutOfBoundsException e) {
해당 되는 예외 처리 코드 1
} catch(NumberFormatException e) {
해당 되는 예외 처리 코드 2
}
catch 문이 여러 개 존재해도 단 하나의 catch 블록만 실행된다.
try 블록에서 동시 다발적으로 예외가 발생하지 않고, 실행되는 순서에 따라 하나의 예외가 발생하면,
즉시 실행을 멈추고 해당 catch 블록으로 이동되어 버리기 때문이다.
ex) CatchByExceptionKindExam.java : 다중 catch 문
public class CatchByExceptionKindExam {
public static void main(String[] args) {
try {
String data1 = args[0];
String data2 = args[1];
int value1 = Integer.parse(data1);
int value2 = Integer.parse(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개 값의 수가 부족합니다.");
System.out.println("[실행 방법] : java CatchByExceptionKindExam num1 num2");
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요");
}
}
}
2. catch 문의 순서
다중 catch 블록을 작성 시 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다.
try 블록에서 예외가 발생하면, catch 블록은 위에서부터 차례대로 검색된다.
만약 상위 예외 클래스의 catch 블록이 위에 존재한다면, 하위 catch 블록은 실행되지 않는다.
하위 예외 클래스는 상위 예외 클래스를 상속했기 때문에, 상위 예외 타입도 되기 때문이다.
3. 멀티 catch 블록
자바 7 버전 부터 하나의 catch 블록에서 여러 개의 예외 처리를 할 수 있도록 catch 기능을 추가 했다.
catch 괄호( ) 안에 동일하게 처리하고 싶은 예외를 | 기호로 연결하면 된다.
'Java 기본 문법 - 참조 서적 [이것이 자바다 - 한빛미디어] > 8. 예외 처리' 카테고리의 다른 글
5. Java 자바 [예외 처리] - 사용자 정의 예외와 예외 발생 시키기, 예외 정보 얻기 (0) | 2020.09.14 |
---|---|
4. Java 자바 [예외 처리] - 예외 떠넘기기 throws (0) | 2020.09.14 |
3. Java 자바 [예외 처리] - 자동 리소스 닫기 try - with - resource 문 (0) | 2020.09.14 |
1. Java 자바 [예외 처리] - 예외와 예외 클래스 (0) | 2020.09.13 |