참고글 

하나의 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

 

 

블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,