Yoon DevLog
article thumbnail

 

 

예외(Exception) 처리하기

프로그램의 실행 도중에 발생하는 에러는 어쩔 수 없지만, 예외는 프로그래머가 이에 대한 처리를 미리 해줘야 한다.

 

예외처리(Exception Handling)란, 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것이다.

또한 예외처리의 목적은 예외의 발생으로 인한 실행 중인 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지할 수 있도록 하는 것이다.

발생한 예외를 처리하지 못하면, 프로그램은 비정상적으로 종료되며, 처리되지 못한 예외는 JVM의 '예외처리기(UncaughtExceptionHandler)'가 받아서 예외의 원인을 화면에 출력한다.

 

 

try - catch 문

예외를 처리하기 위해서는 try-catch문을 사용한다.

try{
	// 에러가 발생할 가능성이 있는 로직을 넣는다.
}catch(Exception1 e1){
	// Exception1 발생했을 경우, 이를 처리하기 위한 로직을 적는다.
}catch(Exception2 e2){
	// Exception2 발생했을 경우, 이를 처리하기 위한 로직을 적는다.
}catch(Exception3 e3){
	// Exception3 발생했을 경우, 이를 처리하기 위한 로직을 적는다.
}

하나의 try블럭 다음에는 여러 종류의 예외를 처리할 수 있도록 하나 이상의 catch블럭이 올 수 있으며, 이 중 발생한 예외의 종류와 일치하는 단 한개의 catch 블럭만 수행된다.

class ExceptionEx{
	public static void main(String args[]){
    	int number = 100;
        int result = 0;
        
        for(int i=0; i<10; i++){
        	try{
            	result = number / (int)(Math.random() * 10);
                System.out.println(result);
            }catch(ArithmeticException e){
            	System.out.println("0"); // ArithmeticException이 
                			 // 발생하면 실행되는 코드
            }        
        }
    }
}

 

 

try-catch문에서의 흐름

try-catch 문에서, 예외가 발생한 경우와 발생하지 않았을 때의 흐름(문장의 실행순서)이 달라진다!



✔︎ try 블럭 내에서 예외가 발생한 경우
   1. 발생한 예외와 일치하는 catch 블럭이 있는지 확인
   2. 일치하는 catch 블럭을 찾게 되면, 그 catch 블럭 내의 문장들을 수행하고 전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행한다. 만일 일치하는 catch블럭을 찾지 못하면 예외는 처리되지 못한다.

✔︎ try 블럭 내에서 예외가 발생하지 않은 경우
   1. catch블럭을 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속한다. 

 

 

public class Exception {
    public static void main(String[] args) {
        int a, b, c;
        try {
        	// ... 
        } catch (NumberFormatException e) {
            System.out.println("숫자로 변환할 수 없습니다.");
        } catch (ClassNotFoundException e) {
            System.out.println("클래스가 존재하지 않습니다.");         
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("실행 매개값의 수가 부족합니다.");
        } catch (IOException e) {
            System.out.println("입력값이 잘못 되었습니다.");
        } catch (NullPointException e) {
            System.out.println("NULL을 참조하고 있습니다.");
        } ...
    }
}

그렇다면 위와같이 꼭 예외처리를 각각 항목별로 선언해야하는가?

그런 것은 아니다. 예외 클래스가 너어어어무 많아서 전체 다 선언할수는 없다. 클래스의 상속 관계를 이용하여 예외클래스의 상위 클래스인

Exception 클래스 타입을 catch문에 선언하면, catch문 단 하나로 모든 예외 발생을 처리할 수 있다.

 

 

멀티 catch 블럭

JDK 1.7부터 여러 catch블럭을 '|' 기호를 이용해서, 하나의 catch블럭으로 합칠 수 있게 되었다. 이를 '멀티 catch블럭'이라 한다.

아래의 코드에서 알 수 있듯이 멀티 catch블럭을 사용하면 중복된 코드를 줄일 수 있다.

try {
    // ...
} catch (NullPointException | ArrayIndexOutOfBoundsExcetion e) {
    // ...
}

 

만일 멀티 catch블럭의 '|' 기호로 연결된 예외 클래스가 조상과 자손의 관계에 있다면 컴파일 에러가 발생한다. 

try {
    // ...
} catch (ParentException | ChildException e) {
    // ...
}

왜냐하면, 두 예외 클래스가 조상과 자손의 관계에 있다면, 그냥 조상 클래스에만 써주는 것과 똑같기 때문이다.

 

 

try-catch-finally 문

try{
	// 에러가 발생할 가능성이 있는 로직을 넣는다.
}catch(Exception1 e1){
	// Exception1 발생했을 경우, 이를 처리하기 위한 로직을 적는다.
}finally{
	// 항상 실행!!!!
}

위에서 정리한 try-catch문에서 finally문이 추가되었는데.. 

기존에 try-catch에서는 프로그램 수행 도중 예외가 발생하면 프로그램이 중지되거나, 예외 처리에 의해 catch 구문으로 빠져버린다.

하지만 어떠한 예외가 발생하더라도 꼭 실행되어야하는 부분이 있다면 finally문으로 처리가 가능하다!

 



예외가 발생한 경우에는 try -> catch -> finally 순서로 실행되고
에외가 발생하지 않은 경우에는 try -> finally 순으로 실행된다.

 

 


 

 

예외 메세지 출력

예외가 발생했을 떄 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨져 있으며, getMessage()printStackTrace()를 통해서 이 정보들을 얻을 수 있다.

 



printStatckTrace() - 예외발생 당시의 호출 스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
getMessage() - 발생한 예외 클래스의 인스턴스에 저장한 메시지를 얻을 수 있다.

 printStackTrace() 는 프로그램의 내부 요소를 자세하게 추적하여 오류 메세지를 내보이기에 이를 외부에 노출시키면 보안적인 문제가 될 수 있으니 관계자만 확인 할 수 있도록 만들어 주는 것이 좋다.

 

try{
    ...
    System.out.println(0/0); // ArithmeticException 예외 발생
    ...
} catch(ArithmeticException e){ // e는 해당하는 에러의 예외정보가 담겨 있는 참조 변수 이다
	// 에러 메세지
    System.out.println(aa.getMessage()); // by zero
	// 상세한 에러 추적 메세지
    e.printStackTrace(); // java.lang.ArithmeticException: / by zero at MyClass.main(MyClass.java:5)
}

 


#참고자료

자바의 정석(남궁성 지음)

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 

 

Inpa Dev 👨‍💻

성장 욕구가 가파른 초보 개발자로서 공부한 내용을 쉽게 풀어쓴 기술 개발자 블로그를 운영하고 있습니다.

inpa.tistory.com

 

profile

Yoon DevLog

@usnooy._.

백엔드 개발자 성장일기 -