[Java] 자바 예외처리 (Exceptions) Try Catch 사용법

반응형

예외처리(Exception)란?

처음 프로그래밍을 하게 되면 그냥 동작하는 것에 중점을 두기 때문에 예외처리는 무시하고 넘어가기 쉽습니다. 예외는 에러(Error)의 범주에 포함됩니다. 에러는 예외를 포함에 시스템의 이상, 하드웨어의 문제등을 포괄적으로 나타내는 개념입니다. 가장 대표적으로 OutOfMemoryError를 말할 수 있습니다. 말 그대로 메모리가 부족해서 시스템이 중단 되는 상황이죠. 예외처리란 예외가 발생할 것을 개발자가 미리 예측해서 이를 제어하고 비정상 종료를 피하기 위한 처리 방법입니다. 자바를 포함한 대부분의 언어들은 이러한 예외상황을 처리하고자 Try Catch 문을 사용해서 처리합니다.

 

다음과 같이 두 문장으로 정리를 할 수 있습니다.

  • 메서드 내에서 오류가 발생했을때 시스템에 던지는 객체
  • 메서드 호출 스택 구조(Method Call Stack)로 예외가 전달된다.

 

Exception은 두 가지 성격으로 나뉩니다.

  • Checked Exceptions (반드시 처리해야 하는 예외)
  • Runtime Exceptions (반드시 처리해야 하지 않아도 되는 예외)

 

 

 

Java Exception 종류

예외 종류 에러 발생 원인
NullPointException 참조 에러 (Null 값 참조)
IOException 입출력 에러
OutOfMemoryException 메모리 부족
ArithmeticException 0으로 나눌 경우
ArrayIndexOfBoundsException 배열 index 범위 초과
NumberFormatException 문자열을 숫자 변환시 발생
ClassCastException 클래스 캐스팅 에러
IllegalArgumentException 인자 오류

Java Exceptions


 

위의 예외중 ArithmeticException의 경우는 Runtime Exception이며 IOException의 경우 Checked Exception입니다. 두 가지 케이스를 비교해가며 알아보겠습니다.

 

 

 

 

Checked Exception

 

 우선 프로젝트를 만들고 다음과 같이 메서드를 설정합니다. 다음은 my.txt라는 파일을 읽어서 해당 파일의 문자열을 출력하는 프로그램입니다. main 함수에서 method1 를 호출하고 method1가 method2를 호출하는 구조입니다. 다음과 같이 FileReader 객체 생성과 readLine 메서드에 에러가 표시되는 것을 확인 할 수 있습니다. 이는 두 작업 모두 Checked Excption를 발생시키기 때문입니다. 그래서 반드시 try catch 구문을 써줘야 하는 것이죠.

IOException


 

 

 다음과 같이 에러를 try catch 문을 구현함으로써 막아줄 수 있습니다. 

 

 

 catch 다음에 추가할 수 있는 finally 구문의 경우 해당 구문이 성공하든 실패하든 마지막에 실행되는 영역입니다. 일반적으로 자원의 해제에 사용이 됩니다. 예를 들어 try 구문에서 "my.txt" 파일이 없어서 예외가 발생한 경우 catch 구문으로 바로 이동되면서 자원의 해제가 되지 않습니다. 물론 catch에 선언을 해도 되긴 하지만 정상적이진 않습니다. 그래서 반드시 finally 구문에서 close 명령을 호출합니다.

 

 

 그런데 또 에러가 납니다. 자원을 해제하기 위한 close() 메서드도 IOException을 발생시키키 때문이죠. 만약 다음과 같이 throws를 사용해서 Specify 처리를 하면 try catch를 하지 않아도 됩니다. 하지만 method2를 호출하는 method1 쪽에서 컴파일 에러가 발생합니다.

Specify 처리 throws IOException


 

 

 이렇게 method1에 try, catch 구문을 포함해서 method2에서 던진 예외를 받아서 처리할 수 있습니다. 

 

 

 만약 method1에서도 예외를 던진다면 main 함수에서 처리해주어야 합니다. 이렇게 반드시 어디선가는 예외를 처리해줘야 하는 경우를 Checked Exception이라고 합니다.

 

 

 저렇게 throw IOException을 통해서 예외를 처리하지 않고 위임을 할 수 있지만 실제로는 예외가 발생하는 method2에서 처리하는 편이 좋습니다. 하지만 다음과 강티 try catch 구문이 중첩되어서 가독성이 많이 떨어집니다. 그래서 나온것이 try-with-resources 구문입니다.

 

 

 만약 try-with-resources 구문을 사용한다면 다음과 같이 조금더 깔끔하게 표현이 가능합니다. try() 괄호 구문안에 해제되어야 할 생성 객체를 포함하는 것이 특징입니다. 단, AutoCloseable 인터페이스를 구현하는 예외에서만 동작합니다.

 

 

 JDK에서 만든 클래스들은 대부분 AutoCloseable 인터페이스를 구현하고 있습니다.

 

 

Runtime Exception

 

 위의 예제에서 method2 부분을 지우고 다음과 같이 단순히 숫자를 0으로 나누어 보겠습니다. 보시다시피 ArithmeticException이 발생합니다. 어떤 수를 0으로 나눌 때 발생합니다. 하지만 ArithmeticException의 경우 Runtime Exception이기 때문에 어떤 컴파일 에러도 발생하지 않습니다. 이 부분이 Runtime Exception과 Checked Exception의 다른 점 입니다.

ArithmeticException


 

 

 다음과 같이 try, catch 구문을 포함하면 비정상 종료를 방지할 수 있습니다.

 

지금까지 자바의 예외처리에 대해서 알아봤습니다. 그냥 자세한 내용을 모르고 무조건 try catch를 사용할 수도 있겠지만 try with resources 같은 구문을 사용하면 코드 가독성이 높아지고 복잡하지 않은 구문을 만들 수 있습니다. 또한 Checd, Runtime 을 구분해서 프로그램을 한다면 보다 올바른 방법으로 예외처리가 가능할 것입니다.

반응형

댓글

Designed by JB FACTORY