티스토리 뷰
컴파일할 때는 문제가 없던 프로그램도 동작 도중에 종종 오류가 발생한다. 사용자가 항상 개발자의 생각대로 프로그램을 사용하지 않기 때문이다. 숫자만 입력해야하지만 문자열을 입력하기도 하고, 파일을 업로드하기 전 파일의 이름을 지정하지 않기도 한다.
이럴 때 발생하는 오류를 사전에 방지하는 것은 중요하다. 그런데 개발자가 이러한 오류가 발생할 때마다 프로그램이 종료되는 것을 원치 않을 수 있다. 오류를 무시하고 싶을 수도 있고, 그 오류가 발생 했을 때 수행할 적절한 동작을 직접 정의하고 싶을 수도 있다. 이럴 때 활용하는 것이 try-catch-finally 구문이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Main { public static void main(String[] args) { int [] arr = new int [ 3 ]; try { System.out.println(arr[ 3 ]); System.out.println(arr[ 2 ]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println( "오류 발생!" ); } finally { System.out.println( "finally..." ); } } } |
위의 예제를 살펴보자 크기가 3인 int 배열을 선언했는데, index 3에 접근을 시도했다. 이 경우, JVM은 ArrayIndexOutOfBoundsException을 발생할 것이다. catch의 역할은 지정한 오류(Exception)이 발생할 경우의 동작을 정의할 수 있도록 도와준다. finally는 try와 catch구문이 끝났을 때 할 동작을 정의할 수 있는 키워드이다. 즉, 위 소스코드의 동작 결과는 아래와 같다.
1 2 | 오류 발생! finally... | cs |
한편, 이러한 try-catch-finally block을 오류가 발생할 만한 모든 구역에 각각 구현하는 것은 조금 번거로운 작업이다. 그래서 throws라는 예약어를 사용하기도 한다. throw는 해당 메소드를 호출한 곳으로 발생한 Exception을 전달한다.(던진다) 아래 예제를 참고하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class Main { public static void main(String[] args) { int [] arr = new int [ 3 ]; try { customFunction(arr); } catch (ArrayIndexOutOfBoundsException e) { System.out.println( "Exception 발생!" ); } } public static void customFunction ( int [] arr) throws ArrayIndexOutOfBoundsException { System.out.println( "함수 호출!" ); System.out.println(arr[ 5 ]); } } |
18번째 줄에서 Exception이 발생했으나, try-catch block 대신, throws를 활용하여 main 메소드에 Exception을 전달했다. 그리고 main 함수에서 예외처리를 진행한다. 이를 활용하면 여러 메소드에서 발생할 수 있는 Exception을 한군데에서 처리할 수 있다. 위 소스코드의 실행 결과는 아래와 같다.
1 2 | 함수 호출! Exception 발생! | cs |
try block에서 자원을 할당하는 로직이 있을 경우, Exception이 발생했을 때 자원이 제대로 해제되지 않을 수 있다. catch block 내부에 자원 해제를 구현하는 방법도 있지만, finally block은 try와 catch의 결과에 상관없이 무조건 실행하는 부분이므로 자원의 해제 로직을 주로 finally에 구현한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class Main { public static void main(String[] args) { InputStream is = null ; OutputStream os = null ; try { is = new FileInputStream( "fileName" ); os = new FileOutputStream( "fileName" ); } catch (FileNotFoundException e) { System.out.println( "파일이 없어서 Exception 발생!" ); } finally { try { is.close(); os.close(); } catch (IOException e) { System.out.println( "자원 해제 도중 Exception 발생" ); } } } } |
위 예제를 살펴보자. 각각 InputStream과 OutputStream 변수에 자원을 할당받았다. 그리고 finally 구문을 통해 안정적으로 해제하고 있는데, 자원 해제에도 예외처리가 필요하여 try-catch 구문을 또 사용하였다. 이렇게보니 조금 번거로워 보인다. 다행히도 JAVA7부터 try-with-resources를 제공한다. 아래 예제를 통해 확인해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Main { public static void main(String[] args) { try (InputStream is = new FileInputStream( "fileName" ); OutputStream os = new FileOutputStream( "fileName" )) { } catch (IOException e) { System.out.println( "Exception 발생!" ); } } } |
try문을 시작할 때 자원을 할당한 것은 비슷하지만, 자원을 해제하는 finally block이 빠진 것을 확인할 수 있다. try-with-resources를 활용하면 할당된 자원을 Exception 발생시에 자동으로 해제할 수 있다. 그래서 JAVA7 이상을 사용한다면 보다 편리하게 try-catch block을 사용할 수 있다.
-끝-
아래의 '공감' 버튼 클릭은 포스팅에 큰 힘이 됩니다.^^
'IT > 기술면접' 카테고리의 다른 글
싱글턴(Singleton)패턴에 대해 자세히 알아보자 (1) | 2018.01.07 |
---|---|
[JAVA] String, StringBuilder, StringBuffer에 대하여 (0) | 2017.10.05 |
[IT 기술면접 준비자료] 신입 SW개발자 기술면접 예상 질문 모음 2 (0) | 2017.04.16 |
[IT 기술면접 준비자료] 신입 SW개발자 기술면접 예상 질문 모음 1 (0) | 2017.04.02 |
[IT 기술면접 준비자료] 웹 아키택처와 WAS(Wep Application Server) (0) | 2017.03.19 |