참고글
하나의 try 블록에서 여러개의 예외가 발생하는 경우 많은 catch블럭이 발생하게 됩니다.
1
2
3
4
5
6
7
8
9
10 |
try{
}catch(예외1 e1){
예외1 처리 로직
}catch(예외2 e2){
예외2 처리 로직
}catch(예외3 e3){
예외3 처리 로직
}
|
cs |
그러나 이렇게 많은 catch문이 발생하면 그 안에서 중복되는 코드들이 발생할 수 있습니다.
예를 들어 e.printStackTrace() 를 통해 예외 정보를 출력하는 로직등이 대표적입니다.
JDK1.7 부터는 이러한 불편함을 해소하기 위해 멀티캐치(multi catch)문을 제공합니다.
멀티 캐치문은 다음과 같이 사용합니다.
하나의 catch 안에 '|' 논리연산의 or에 해당하는 기호를 사용하여 여러개의 예외를 연결할 수 있습니다.
1
2
3
4
5 |
try{
}catch(예외1 | 예외2 | 예외3 e){
공통 예외로직 ex)e.printStackTrace();
} |
cs |
멀티캐치 사용시 주의사항
멀티캐치는 상황에 따라 사용함으로써 간편하게 여러가지의 예외를 하나의 로직으로 처리할 수 있다는 장점이 있습니다.
그러나 그에 따른 제한사항 및 주의사항이 존재합니다.
1. Multi Catch문에 사용된 예외들은 예외의 상속관계에서 부모와 자식관계에 있으면 안됩니다.
다음의 경우에는 catch문에 ArithmeticException와 RuntimeException을 동시에 처리하려 하고 있습니다.
1
2
3
4
5 |
try{
}catch (ArithmeticException | RuntimeException e) {
} |
cs |
1
2 |
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The exception ArithmeticException is already caught by the alternative RuntimeException |
cs |
그러나 이대로 컴파일 하게되면 위와 같은 예외가 발생하게 되는데 그 이유는 다음과 같습니다.
ArithmeticException은 RuntimeException의 자손 클래스이기 때문에 RuntimeException 하나만으로 처리가 가능하기 때문입니다.
컴파일러 입장에서는 불필요한 코드라고 판단했고 위 코드를 바람직하게 고친다면 다음과 같이 고칠 수 있을것입니다.
1
2
3
4
5 |
try{
}catch (RuntimeException e) {
RuntimeException 하나로 하위 예외들을 모두 처리
} |
cs |
2. Multi Catch문에 사용된 예외들의 공통된 조상의 멤버만 사용할 수 있다.
여기서 멤버란 멤버메서드 및 멤버변수를 의미합니다.
이게 무슨뜻일까요? Multi Catch문에서는 하나의 참조변수로 예외를 처리한다는 사실을 깨달았을 것입니다.
1 |
catch(ExA | ExB | ExC e) // e라는 참조변수 하나로 처리 |
cs |
이러한 경우에 예외가 발생했을 때 e라는 참조변수가 가리키는 객체어 어느 예외 클래스의 인스턴스인지 알 수 없게 됩니다.
다음 코드에서는 예외가 발생했을 경우 ExA 예외의 메서드를 호출하게 되는데 만약 실제 발생한 예외가 ExB 였다면 해당 메서드가 존재하지 않을 수 있습니다.
1
2
3
4 |
try{
}catch(ExA | ExB | ExC e){
e.methodA(); //e가 어느 예외인지 예측 불가능하므로 불가능한 코드
} |
cs |
이러한 이유로 멀티캐치문에는 공통된 조상의 메서드만 호출하거나 정확이 어느 예외의 인스턴스인지 판단하여 캐스팅(형변환) 후 해당 메서드를 사용해야 합니다.
1
2
3
4 |
try{
}catch(ChildExA | ChildExB | ChildExC e){
e.parentsMethod(); //공통조상인 parentsMethod()만 호출 가능
} |
cs |
instanceof 연산을 통해 어느 예외의 인스턴스인지 판단 후 캐스팅해준 후 메서드를 사용합니다.
다만 이런 if문이 나타난다는 뜻은 예외별로 다른 처리가 필요하다는 뜻이므로 이런 경우에는 멀티캐치문이 아닌 평소대로 여러개의 캐치문을 사용하도록 하는것이 좋습니다.
1
2
3
4
5
6
7
8
9
10 |
try{
}catch(ChildExA | ChildExB | ChildExC e){
if(e instanceof ChildExA){
ChildExA a = (ChildExA)e; //캐스팅
a.childMethodA();
}else if(e instanceof ChildExB){
ChildExB b = (ChildExB)e; //캐스팅
b.childMethodB();
}else{ ... }
} |
cs |
'자바[Java]' 카테고리의 다른 글
[JAVA] 자바의 탄생 및 역사 (0) | 2017.12.19 |
---|---|
[JAVA] 자바 향상된 예외 처리 - try - with - resources 문 (0) | 2017.12.16 |
[JAVA] 예외의 회피 (0) | 2017.12.09 |
[JAVA] 자바 예외 처리 방법 (Exception Handling) (2) | 2017.12.09 |
[JAVA] 자바에서 예외(Exception)란? (0) | 2017.12.07 |