JAVA exception 처리하기
안녕하세요, cx 사업본부 박토끼입니다. 요즘 일을 하면서 계속 머리속에서 드는 의문이 하나 있었습니다. "예외 처리를 어떻게 해야 잘 처리하는 것일까?"
사실 Java를 처음 배울 때는 exception에 그다지 민감하지 않았습니다. 단순히 '잘못되어서 에러가 나는구나.' 정도의 생각만 했습니다. 그리고 throw 키워드나 try~catch 블럭을 사용하면서도, IDE 툴에서 빨간색 표시로 잘못되었다고 에러가 뜨고 컴파일 자체가 안되니까 해줘야된다는 생각뿐이었습니다.
그리고 일을 시작한 후에도 exception 처리가 왜 필요한지 느끼지 못했습니다. '에러가 나는 것 자체가 문제이니, 에러가 안나게 로직을 완벽히 수정하는 것이 옳다. 그러면 exception 처리는 필요없다.' 라고 생각했습니다. 지금 생각해보면 아주 근시안적 생각이었고, exception이 발생하는 이유는 꼭 로직의 오류가 아니라 다른 원인이 있을 수 있다는 것을 전혀 인지하지 못했던 것 같습니다. 또한 exception 처리를 제대로 하지 않으면 서비스 중인 프로그램이 중단되어 사용자에게 매우 불편을 끼칠 수 있다는 생각도 하지 못했던 것 같습니다.
점점 반성문이 되어가는 것 같네요.(!) 반성은 그만하고 이제 java 에서 exception이란 무엇이며, 어떻게 처리해야 하는 지 알아보도록 하겠습니다.
1. Exception 이란?
Java에서 Exception 이란 프로그램의 실행중에 발생하는 문제입니다. 예외가 발생하면 프로그램의 정상적인 플로우가 중단되며, 프로그램 혹은 애플리케이션이 권장하지 않는, 비정상적인 방법으로 종료됩니다. 그러므로 예외는 처리되어야 합니다.
예외는 매우 다양한 원인으로 인해 발생하는데, 프로그래밍에서는 에러를 세 가지 카테고리로 분류합니다.
컴파일 에러(Compile-time Errors) : 작성한 소스 코드를 빌드할 시 컴파일러에 의해서 파악되는 에러입니다.
런타임 에러(Run-time Errors) : 프로그램 실행중에 발생하는 에러입니다. 종종 프로그램의 충돌을 유발합니다.
로직 에러(Logic Errors) : 프로그램 로직 상의 에러입니다. 이런 종류의 에러는 에러메시지가 나지 않으며, 종종 이런 에러는 무한 루프, 실행해야되는 코드의 지나침, 올바르지 않은 결과를 유발합니다.
- 사용자가 유효하지 않은 데이터를 입력하는 경우
- 열릴 필요가 있는 파일을 찾을 수 없는 경우
- 커뮤니케이션 중에 네트워크 커넥션을 잃는 경우 혹은 JVM의 메모리가 부족한 경우
- Checked exceptions : 컴파일 시 발생하는 에러입니다. 이는 위에서 컴파일 시 예외라고 불리기도 합니다. 이 예외들은 컴파일 시에 단순히 무시하고 지나갈 수 없으며, 프로그래머는 반드시 이 예외들을 처리야해만 합니다. 예를 들어, 파일에서 데이터를 읽기 위해 FileReader 클래스를 사용하는데, 생성자에 쓰인 파일이 존재하지 않는다면 FileNotFoundException이 발생할 것입니다. 그리고 컴파일러는 프로그래머에게 예외처리를 하라고 알려줍니다.
- Unchecked exceptions : 실행 시에 발생하는 예외로, 런타임 에러라고도 불립니다. 로직 에러 혹은 API의 부적절한 사용 등의 프로그래밍 버그를 포함합니다. 예를 들어, 사이즈가 5개인 배열을 선언하고 6번째의 요소를 호출한다면, ArrayIndexOutOfBoundsException 예외가 발생합니다.
- Errors : 이는 전혀 예외가 아니라, 사용자의 조작 혹은 프로그래머를 넘어서 발생하는 문제입니다. 에러는 코드에서 일반적으로 간과되는데 왜냐하면 에러에 대해서 프로그래머가 할 수 있는 것은 거의 아무것도 없기 때문입니다. 예를 들어, 만약 stack overflow 가 발생하면, 에러가 발생할 것입니다. 이런 에러들은 또한 컴파일 시에도 간과됩니다.
모든 exception 클래스들은 java.lang.Exception 클래스의 하위유형(subtype)입니다. exception 클래스는 Throwable 클래스의 서브클래스입니다. exception 클래가 아닌 쪽에는 Error라고 불리는 다른 서브클래스가 있으며, 이는 Throwable 클래스에서 파생된 것입니다.
에러는 심각한 실패의 경우에 발생하는 비정상적인 조건입니다. 이는 Java 프로그래밍으로 처리되지 않습니다. 런타임 환경에서 실행되는 에러를 나타내기 위해 Error가 발생됩니다. 예를 들어, JVM이 out of memory되는 경우 입니다. 보통 프로그램은 이런 에러가 발생하면 회복될 수 없습니다.
아마도 Exception의 서브클래들 중에서는 익숙한 것들도 있으실 겁니다. 예를 들어, NullPointerException,
ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException, NumberFormatException,
IllegalArgumentException, ClassNotFoundException, InputMismatchException 등은 프로그래밍을 하면서 많이 접해보셨을 거라 생각합니다.
예외에 대한 기본적인 개념은 살펴봤는데요, 그렇다면 어떻게 예외를 처리하는 것이 좋은지 10가지 사항을 기술해보도록 하겠습니다.
- 구체적인 예외를 사용하기
- 예외는 일찍 던지기
- 캐치는 늦게
- 리소스 닫기
try(FileReader fr=new FileReader("E://file.txt")){ char [] a = new char[50]; fr.read(a); // reads the contentto the array for(char c : a) System.out.print(c); //prints the characters one by one }catch(IOException e){ e.printStackTrace(); }
- 예외를 로그로 남기기
- 다양한 예외들을 위한 하나의 캐치 블럭
- 커스텀한 익셉션을 사용하기
- 네이밍 관습과 패키징
- 분별력 있게 예외 사용하기
- 예외를 발생 문서화하기
참고
http://www.tutorialspoint.com/java/java_exceptions.htm
http://www-acad.sheridanc.on.ca/~jollymor/prog24178/oop2.html
'백엔드' 카테고리의 다른 글
[JAVA]Composite 패턴과 재귀호출로 파일탐색기 만들기 - 1 (1) | 2016.08.01 |
---|---|
Git merge, rebase 이해하기 (0) | 2016.07.29 |
Git의 내부구조 (0) | 2016.05.20 |
java 8 Lambda Expression (0) | 2016.05.02 |
[MongoDB 기초] 윈도우 설치부터 Java에서 사용까지! (2) | 2016.03.25 |