예외처리
Java에서는 예외를 두 가지로 분류한다.
- 체크 예외 (Checked Exception)
try-catch-finally
로 예외를 처리하거나 메서드 선언부에throws
를 사용해서 예외를 호출한 곳으로 위임하지 않으면 컴파일 오류가 발생한다.RuntimeException
을 제외한Exception
클래스의 자식 클래스
- 언체크 예외 (Unchecked Exception)
- 런타입 시에 예외가 발생하기 때문에 컴파일 시 오류가 발생하지 않아서 예외가 발생하지 않도록 주의해야 한다.
RuntimeException
클래스의 자식 클래스
try-catch-finally 와 throws 의 차이
try-catch-finally
구문은 예외를 처리하고 프로그램의 흐름을 제어할 때 사용하고, throws
구문은 메소드에서 발생할 수 있는 예외를 호출한 쪽으로 알릴 때 사용한다.
둘의 차이점은 예외를 직접 처리하는지 아니면 예외처리를 호출한 쪽으로 위임하는지이다.
특히 throws
는 트랜잭션과 밀접한 관련이 있다.
트랜잭션은 하나의 작업 단위를 뜻한다.
예를 들어 한 트랜잭션이 A, B, C 라는 작업으로 이루어져 있을 때 A, B, C 중 예외가 발생하면 트랜잭션을 실행하기 전 단계로 되돌려야 할 것이다.
이 때 throws
를 이용해서 예외처리를 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void transaction() {
try {
A();
B();
C();
} catch(Exception e) {
// reset
}
}
void A() throws Exception {
}
void B() throws Exception {
}
void C() throws Exception {
}
메서드에 예외를 선언할 때 일반적으로 RuntimeException 들은 적지 않고 반드시 처리해줘야 하는 예외들만 선언한다.
멀티 catch 블럭
JDK1.7부터 여러 catch 블럭을 |
기호를 이용해서 하나의 catch 블럭으로 합칠 수 있다.
1
2
3
4
5
try {
...
} catch (ExceptionA | ExceptionB e) {
...
}
try-with-resources 문
JDK1.7부터는 사용한 자원을 자동으로 해제해주는 try-with-resources
문을 사용할 수 있다.
1
2
3
4
5
// 괄호 안에 두 문장 이상 넣을 경우 ';' 으로 구분한다.
try (FileInputStream fs = new FileInputStream("test.txt");
DataInputStream ds = new DataInputStream(fs)) {
...
}
단, 자동으로 자원을 해제하기 위해서는 Closeable
인터페이스를 구현해야 한다.
예외 되던지기
1
2
3
4
5
6
7
8
static void method() throws Exception {
try {
/* 예외 발생 */
} catch (Exception e) {
/* 예외 처리 */
throws e;
}
}
예외 되던지기는 메서드에서 예외를 catch 하고 catch 블럭에서 다시 예외를 발생시켜 예외를 메서드 내부와 호출한 곳 둘 다 처리하도록 하는 것
하나의 예외에 대해서 예외가 발생한 메서드와 이를 호출한 메서드 양쪽 모두에서 처리해줘야 할 작업이 있을 때 사용한다.
원인 예외
모든 예외는 원인을 지정할 수 있는데, 예외의 원인을 지정하는 이유는 여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위해서이다.
예시.1
1
2
3
4
5
6
7
try {
...
} catch (NullPointerException e) {
Exception ex = new Exception("exception");
ex.initCause(e);
throws ex;
}
혹은 checked 예외를 unchecked 예외로 처리하기 위해 사용한다.
예시.2
1
2
3
void method() {
throw new RuntimeException(new Exception("exception"));
}