예외 처리


일반 예외의 경우는 소스 파일을 컴파일할 때 컴파일 에러를 발생시켜 개발자가 강제적으로 예외 처리 코드를 작성하도록 요구한다. 하지만 실행 예외의 경우는 컴파일러가 체크해주지 않기 때문에 개발자의 경험을 바탕으로 예외 처리 코드를 작성해야 한다.

예외 처리 코드


○try-catch-finally 블록
생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해준다.

try { //1.예외 발생가능 코드 } catch(예외클래스 e) { //2.예외 처리 } finally { //3.항상 실행 }

try-catch-finally 블록은 상기와 같이 작성한다. try구문에서는 예외 발생 가능성이 있는 코드를 작성하며 catch 구문에서는 예외가 발생했을 경우 필요한 코드를 작성하고 finally 구문은 예외의 발생 여부에 상관없이 항상 실행이 필요한 코드를 작성한다. 따라서 예외가 발생했을 경우는 ①→②→③의 순서대로 코드가 실행되며 예외가 발생하지 않았을 경우는 ①→③의 순서대로 코드가 실행된다.

○다중 catch
try구문에서 한 가지 예외만 발생하는 것이 아니라 다양한 예외가 발생할 수 있다. 이러한 한 가지 이상의 예외가 발생할 경우 예외에 따라서 예외 처리 코드를 다르게 하기 위해서는 다중 catch구문을 작성해야 한다.

try { //ArrayIndexOutOfBoundsException 발생 //NumberFormatException 발생 } catch(ArrayIndexOutOfBoundsException e) { //예외 처리1 } catch(NumberFormatException e) { //예외 처리2 }

catch 구문이 여러 개라도 단 하나의 catch 구문만 실행된다. 그 이유는 try 구문에서 동시 다발적으로 예외가 발생하지 않고 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch블록으로 이동하기 때문이다. 따라서 위의 다중 catch구문에서 ArrayIndexOutOfBoundsException이 발생했을 경우는 예외처리1만 실행되고 NumberFormatException이 발생했을 경우는 예외처리2만 실행되게 된다.

이러한 다중 catch를 사용할 경우 catch의 순서 또한 중요하게 봐야 할 부분이다. 상위 예외 클래스의 catch 구문이 위에 있다면 하위 예외 클래스의 catch 구문은 실행되지 않게 된다. 그 이유는 하위 예외는 상위 예외를 상속했기 때문에 상위 예외 타입도 되기 때문이다.

try { //ArrayIndexOutOfBoundsException발생 } catch(Exception e) { //예외 처리1 } catch(ArrayIndexOutOfBoundsException e) { //예외 처리2 }

위의 다중 catch구문을 보면 ArrayIndexOutOfBoundsException이 발생했을 경우 ArrayIndexOutOfBoundsException은 Exception을 상속받기 때문에 예외 처리1만 실행되며 예외 처리2가 실행되는 경우는 없다.

예외 떠넘기기


메소드 내부에서 예외가 발생할 수 있는 코드를 작성할 때 try-catch 블록으로 예외를 처리하는 것이 기본이지만, 경우에 따라서는 메소드를 호출한 곳으로 예외를 떠넘길 수 있다. 이때 사용하는 키워드가 throws이다. throws키워드는 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다. throws키워드 뒤에는 떠넘길 예외 클래스를 쉼표로 구분해서 나열해서 사용하게 된다. 또한 throws키워드가 붙어 있는 메소드는 반드시 try구문 내에서 호출되어야 한다. 아래 그림을 보면 method2는 예외를 떠넘기기 위하여 throws를 사용하였기 때문에 method2를 호출한 method1에서는 try-catch구문을 사용하여 예외를 처리한 것을 볼 수 있다.

public void method1() { try { method2(); } catch(ClassNotFoundException e) { //예외 처리 코드 System.out.println("클래스가 존재하지 않습니다"); } } public void method2() throws ClassNotFoundException { Class clazz = Class.forName("java.lang.String2"); }

main()메소드에서도 throws 키워드를 사용해서 예외를 떠넘길 수 있는데 이럴 경우 결국 JVM이 최종적으로 예외를 처리하게 된다. 이러한 main()메소드에서의 throws키워드는 좋지 못한 예외 처리이다. 그 이유는 JVM은 예외의 내용을 콘솔에 출력하는 것으로 예외를 처리하기 때문에 JVM이 예외를 처리하게 되면 예외 내용을 출력하고 프로그램이 종료되기 때문이다.

'JAVA' 카테고리의 다른 글

람다식(Lambda Expression)  (0) 2022.07.17
enum  (0) 2022.01.16
JAVA 실행과정 & JVM  (0) 2022.01.09
예외  (0) 2022.01.01
final & static  (0) 2021.12.31

+ Recent posts