-
Java: 오류Error와 예외Exception, Unchecked와 CheckedJava 2022. 6. 17. 17:44
Java: 오류Error와 예외Exception, Unchecked와 Checked
이 글에서는...
- 오류와 예외를 구분해 설명하고, Unchecked Exception과 Checked Exception을 구분지어 설명해봅니다.
- 예외의 적절한 처리를 알아봅니다.
일단, 오류Error와 예외Exception
오류와 예외 메시지를 받아주는
Throwable
밑에는 두 클래스가 존재합니다. Error와 Exception이죠.
Java API Docs에서는 이렇게 설명하고 있습니다.Error : (파파고 번역) 오류는 적절한 응용 프로그램이 탐지하려고 해서는 안 되는 심각한 문제를 나타내는 폐기 가능한 하위 클래스입니다. 이러한 오류는 대부분 비정상적인 상태입니다. 스레드 데스 오류는 "정상" 상태이긴 하지만 대부분의 응용 프로그램에서 오류를 감지하려고 하면 안 되기 때문에 오류의 하위 클래스이기도 합니다. 메소드는 메소드를 실행하는 동안 발생할 수 있지만 잡히지 않는 오류의 하위 클래스를 폐기 절에 선언할 필요가 없습니다. 이러한 오류는 절대 발생해서는 안 되는 비정상적인 조건이기 때문입니다. 즉, 오류와 해당 하위 클래스는 예외의 컴파일 시간 확인을 위해 확인되지 않은 예외로 간주됩니다.
Exception : (역시 파파고 번역) 예외 클래스와 해당 하위 클래스는 적절한 응용 프로그램이 탐지하고자 하는 조건을 나타내는 폐기 가능 형식입니다. 예외 클래스 및 런타임의 하위 클래스가 아닌 모든 하위 클래스예외는 검사된 예외입니다. 메서드 또는 생성자의 실행에 의해 제거되고 메서드 또는 생성자 경계 밖으로 전파될 수 있는 경우 확인된 예외는 메서드 또는 생성자의 스로우 절에 선언되어야 합니다.
제가 이해한 바를 다시 말해볼게요.
- 오류는 응용프로그램이 예상할 수 없고 예상할 필요도 없는 비정상적 상태/조건입니다. 예외를 컴파일 타임에 구분하기 위한 목적으로, 오류는 '검출되지 않은 예외'로 간주됩니다(Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions).
- 예외는 런타임예외와 그 하위 클래스들을 제외하곤, 메서드나 생성자 혹은 그 바깥(호출한 쪽)에서 프로그램의 의도에 따라 적절히 처리되어야 합니다(The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions).
Checked Exception과 Unchecked Exception
사실 봐도 봐도 잘 모르겠습니다. 하지만 이것만큼은 확실한 것 같아요.
컴파일 타임에 검증 가능하다면 Checked다. 즉, 적절한 처리를 해두어야 한다.
참 당연한 말이죠? 컴파일 타임에, 그니까 코드 레벨에서 일어날 것을 예상할 수 있다면, 코드 레벨에서 대응을 해두는 것이 상식적이겠죠.
언체크드는 다룰 방법이 없으니 따로 이야기 할 것이 없고요.
체크드 익셉션을 처리하는 방법은 크게 세 가지가 있습니다.Checked Exception를 처리하는 세 가지 방법
1. 예외 복구 : 바로 예외를 throw||throws 하지 않고, 몇 번의 재시도 기회 혹은 얼마 간의 텀을 갖고 다시 수행해보는 것입니다. 그래도 적절하게 수행되지 못한다면 그때 예외를 발생시킵니다.
2. 예외 전환 : throws 하되, 더 상세한(혹은 적절한) 예외로 바꾸어 던지는 것을 말합니다. 예외를 받는 쪽에서 상황을 더 잘 이해할 수 있도록 포장해서 던진다고 보면 될 것 같아요.
3. 예외 회피 : 그대로 다시 던지는 것throws입니다. 예외에 아무 책임도 지지 않는다는 점에서, 셋 중에서는 가장 부적절한 처리라고 할 수 있을 것 같아요. 불가피한 경우에만 사용해야 할 듯 합니다.
- 정말 하면 안되는 행동 : catch블록에서
catch(Exception e) { System.out.println(e); /* or do nothing */}
와 같은 식으로 로그만 찍고 아무 것도 하지 않는 것. 로그가 찍힌 걸 발견하지 못하면 예외가 발생했는지 말았는지도 알 수 없게 되는, 최악의 대응입니다. - 정말 하면 안되는 생각 : 'Unchecked는 롤백해야 하고, Checked는 롤백하면 안된다?' 정말 그럴까요? 블로그 서칭을 하다 보면 이런 내용의 표가 정말 많이 보이는데, 잘못된 생각일 수 있습니다. checked 여부와 트랜잭션 롤백 여부는 상황에 따라 다릅니다. 자신이 대응하려는 예외처리가 상황에 적절한지 항상 명확히 고려해야 합니다.
마무리
평소에 생각지 못하고 있었던 부분인데, 막상 생각해보니 애매하게 느껴지기도 하고 어려웠던 것 같습니다. 정상적인 실행 흐름도 중요하겠지만 비정상적인 흐름도 잘 처리할 수 있도록 더욱 열심히 공부를 해야겠다고 생각되는 시간이었습니다. 화이팅!
'Java' 카테고리의 다른 글
PS tip: 그래프 탐색의 자료구조 - ArrayDeque (3) 2022.07.26 Java: 어플리케이션 실행 옵션 비교 - VM Options / Program Arguments (0) 2022.07.19 Java: Arrays.fill()과 Arrays.setAll()의 차이 (1) 2022.07.12 Java: Integer.parseInt()와 Integer.valueOf()의 차이점 구분 (2) 2022.06.06 Java: Comparable(compareTo())와 Comparator(compare())의 차이점 (0) 2022.05.17 Java: String[] split(regex, limit) 사용 예시 (0) 2022.05.17