자바에서 예외는 checked (체크 예외)와 unchecked (체크하지 않은 예외)로 구분됩니다.
Exception에서 상속되지만 RuntimeException에서는 상속되지 않습니다. 컴파일러는 이를 명시적으로 try-catch를 통해 처리하거나 throws로 선언할 것을 요구합니다.RuntimeException에서 상속됩니다. 컴파일러는 이들을 반드시 처리할 것을 요구하지 않습니다.public void readFile(String file) throws IOException { /* ... */ } // checked public void divide(int a, int b) { int res = a/b; } // unchecked (ArithmeticException)
주요한 점은 checked 예외는 예상되는 복구 가능한 상황(예: 입력/출력 오류)에서 사용되고, unchecked 예외는 프로그램 로직의 오류나 복구할 수 없는 비극적인 상황(예: NullPointerException)에서 사용됩니다.
질문: 귀하의 메서드가 unchecked 예외를 발생시킬 수 있을 경우 이를 처리하거나 throws로 선언해야 합니까?
답변: 아니요. 컴파일러는 복구할 수 없는 (unchecked) 예외를 체크하거나 선언할 것을 요구하지 않습니다. 이들의 처리는 귀하의 재량입니다; try-catch를 사용할 수 있지만, 자주 전역 핸들러까지 "떨어지"게 두기도 합니다.
public void foo() { throw new IllegalArgumentException(); } // 처리나 선언이 필요 없음
이야기
금융 API 프로젝트에서 입력/출력 오류 처리 시 checked 대신
RuntimeException을 발생시켰습니다. 그 결과, 클라이언트는 이를 처리해야 할 필요성이 없어 서버와의 연결 손실 시 잘못된 작동을 초래하고, 애플리케이션이 사용자에게 알리거나 "떨어짐" 없이 종료됐습니다.
이야기
개발자가 메서드 시그니처에 과도한
throws Exception을 선언하여 (예: 데이터베이스) 상위에서 모든 사용 메서드가 try-catch하거나 또한 throws를 해야 했습니다. 이는 코드를 어지럽히고 가독성을 저하시켰으며 리팩토링을 어렵게 만들었습니다.
이야기
한 마이크로서비스에서 모든 예외를 일반
catch (Exception e)로 잡았습니다. 이것은 unchecked 예외(예:NullPointerException)도 가로잡혀 심각한 오류를 "조용히" 무시하게 되어 잘못된 데이터로 서비스가 운영되었습니다.