본문 바로가기
Java

[자바 스터디] #9 - 예외처리

by zannew 2021. 2. 18.

 목표

자바의 예외 처리에 대해 학습하세요.

 

▣ 학습할 내용

  • 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
  • 자바가 제공하는 예외 계층 구조
  • Exception과 Error의 차이는?
  • RuntimeException과 RE가 아닌 것의 차이는?
  • 커스텀한 예외 만드는 방법

 

▶ 9-1 자바에서 예외 처리 방법(try, catch, throw, throws, finally)

▷ 예외처리(exception handling)란?

예외의 발생을 대비해 코드를 작성하는 것을 의미한다. 프로그램의 비정상적 종료를 막고, 정상실행 상태 유지에 목적을 둔다.

▷ Checked Exception 과 Unchecked Exception 

컴파일 시 Checked Exception 이 발생할 가능성이 있는 코드라면 반드시 try-catch로 감싸거나 throw로 던져서 예외처리를 한다. 필수적으로 처리해야하는 예외이다.

반면, 런타임 시 발생하는 Unchecked Exception은 선택적 예외처리를 할 수 있다. 개발 시 부주의로 발생하는 경우가 많아 굳이 예외처리를 할 필요가 없도록 되어있다.

 

▷ try-catch 예외처리

try {
	
    //예외가 발생할 수 있는 코드
    
} catch (FirstException e){

	// 예외가 FirstException 관련 에러일 경우, 이를 처리하는 문장
    
} catch (SecondException e){

	// 예외가 SecondException 관련 에러일 경우, 이를 처리하는 문장

} catch (NException e){

	// 예외가 ThirdException 관련 에러일 경우, 이를 처리하는 문장

}

※ if문과 달리 블럭 안에 있는 문장이 단 한 문장이라고 중괄호{ }를 생략할 수 없다.

▷ try-catch 흐름

예외 발생 시,

1. 발생한 예외와 일치하는 catch블럭이 있는 지 확인

2. 일치하는 catch블럭을 찾으면 해당 블럭 안의 문장을 수행하고 전체 try-catch문을 빠져나간다. 그 다음 문장을 계속해서 수행해 나간다. 만약 일치하는 catch블럭이 없다면 예외처리가 되지 못한다.

예외가 발생하지 않았을 시,

1. catch블럭을 커치지 않고 try-catch문을 빠져나가 다음 문장을 계속 수행해 나간다.

 

여러 종류의 예외가 존재하므로 이를 처리할 수 있도록 한 개 이상의 catch 블럭이 존재할 수 있다. 여러 개의 catch블럭 중 예외 종류와 일치하는 catch블럭 안에 있는 코드만 실행된다. 일치하는 예외가 없으면 예외 처리가 되지 않기 때문에 Exception(모든 예외의 최상위 클래스)로 catch블럭을 만들어서 예외처리를 하기도 한다. 

try-catch블럭을 중첩되게 사용할 수도 있다. 무슨말인가 하면 try블럭안에 또다른 try-catch블럭을 사용할 수 있다는 뜻이다. 단, Exception 참조변수명이 중복되지 않도록 주의해야한다. 

▷ multi catch블럭

여러개의 catch블럭을 '|'기호를 사용하여 하나의 catch블럭으로 만들 수 있다. 중복된 코드를 줄일 수 있다는 장점이 있다. 예외 클래스의 개수에는 제한이 없다. 단, 나열되는 예외클래스들이 서로 상속관계에 있으면 안된다. (한쪽에서만 미리 처리된다.)

try {

} catch (FirstException | SecondException e){

}

 

▷ throw와 throws

throw는 고의로 예외를 발생시킬 때 사용하는 키워드다. 예외클래스의 참조변수를 throw해서 특정 예외를 더 구체적으로 처리하고자 할 때 활용할 수 있다.

class ThrowTest {

	public static void main(String[] args){
    	try{
              Exception e = new Exception("쓰로우 예외 테스트");
              throw e;
        }catch (Exception e){
        	System.out.println("에러 메시지 : "+e.getMessage());
            e.printStackTrace();
        }
        System.out.println("테스트 종료");
    }
}

// 출력 : 

에러 메시지 : 쓰로우 예외 테스트
java.lang.Exception: 쓰로우 예외 테스트
at ThrowTest.main(ThrowTest.java:5)
테스트 종료

 

throws는 메서드 선언 시 throws키워드를 사용하여 예외 클래스를 함께 작성하여 해당 메서드를 호출하는 쪽에서 예외를 처리하도록 떠넘기는 것이다. 예외를 전달받은 메서드(호출한 쪽)가 또다른 메서드에서 호출된다면 해당 메서드쪽으로 예외처리를 다시 전가하는 것도 가능하다.

▷ finally

finally는 예외 발생여부에 관계없이 실행되어야할 코드를 작성하기 위한 목적으로 사용할 수 있다. try-catch 블럭에서 마지막에 위치하는 블럭이다. 선택적으로 사용할 수 있다. 예외가 발생한 경우 try-> catch -> finally 블럭 순으로 이동하고, 예외가 발생하지 않는 경우 try -> finally블럭 순으로 이동한다.

▷ try-with-resources

// 객체가 여러개 필요할 땐 세미콜론으로 구분짓는다. 
// 해당 객체들은 모두 AutoCloseable인터페이스를 구현한 객체여야만 한다.

try(객체 생성 문장[; 객체 생성 문장2]){
	/*
    try에서 만들어진 객체들은 이 블럭을 벗어나는 동시에 close()가 수행된다.
    */
}catch (Exception1 e){

}catch (Exception2 e){

}finally {

}

자바 7버전부터 추가된 기능으로 exception시 해당 리소스를 자동으로 close한다. 주로 파일입출력 예외처리에 쓰인다.

 

 

 

▶ 9-2 자바가 제공하는 예외 계층 구조

출처 : http://www.tcpschool.com/java/java_exception_class

 

▶ 9-3 Exception과 Error의 차이는?

 

에러는 메모리 부족(OutOfMemoryError)이나 스택오버플로우(StackOverFlowError)같이 발생 시 복구할 수 없는 심한 오류등을 의미하고, 예외는 발생하더라도 수습이 될 수 있는 비교적 덜 심각한 것이다.

에러가 발생한다면, 프로그램의 비정상적 종료를 막을 방법이 없지만, 예외는 발생하더라도 개발자가 적절한 처리 코드를 미리 작성하여 프로그램이 비정상적 종료를 막는다. 

 

 

▶ 9-4 RuntimeException과 RE가 아닌 것의 차이는?

 

▶ 9-5 커스텀한 예외 만드는 방법

 

예외를 커스터마이징하기 위해서 최상위 클래스 Exception을 상속받아야 한다. 그 다음 생성자를 만들어 출력할 메시지를 받아 출력할 수 있다.

디폴트 생성자보다는 메시지 등 알아볼 수 있는 내용을 보여주는 생성자를 만드는 것이 좋다. 디폴트 생성자로 예외처리를 하면 좀더 구체적인 에러메시지를 확인할 수 있다.

class CustomizedException extends Exception {
	
    CustomizedException(){}
    
    CustomizedException(String msg){
		super(msg);
	}
}

 

기존의 예외 클래스는 주로 Exception을 상속받아 'checked 예외'로 작성하는 경우가 많았지만, 요즘 예외처리를 선택적으로 할 수 있도록 RuntimeException을 상속받아서 작성하는 방향으로 바뀌어가고 있다. 

 

 

 

 

백기선님의 자바 라이브 스터디 커리큘럼을 따라 공부하고 있습니다. 

잘못된 점이나 보충할 부분이 있으면 코멘트 남겨주세요

작은 조언이 저에겐 성장의 원동력이 됩니다 :-)

댓글