2025-09-15
1일 1아티클
LY
예외 과대 포장
배경
- 한 곳에서 여러 예외가 발생하는 경우
- 다른 예외를 만들어서 감싸는 것보다는, 중요한 예외를 먼저 던져서 명확히 표현할 것
예시
// BEFORE: 두 예외를 합쳐 새로운 예외로 '과대 포장'하는 방식
try {
// 1. 주요 로직 실행
throw new IOException("파일 쓰기 실패!");
} finally {
try {
// 2. 정리 로직 실행
throw new SQLException("연결 해제 실패!");
} catch (SQLException sqlEx) {
// IOException과 SQLException을 합쳐서 전혀 다른 DisposableException을 던짐
throw new DisposableException(ioEx, sqlEx);
}
}
Java에서의 처리 방법
- Java에서는 확인된 예외 발생 시, 다른 예외로 감싸도 예외를 유형별 구분 가능
- 주의해야 할 점
- 호출자에서 여러 종류의 예외를 처리하며, 예외에 부모-자식 관계 있는 경우
- ex.
IOException
과Exception
으로 catch 시,IOException
을 다른 예외로 바꾸면Exception
으로 잡힘 → 컴파일 에러 X
- ex.
- 확인되지 않은 예외로 변환한 경우
- ex.
RuntimeException
으로 감싸면 catch/throws 없이도 컴파일 성공, 복구가 불가능한 경우에만 확인된 예외를RuntimeException
으로 감싸기
- ex.
- 호출자에서 여러 종류의 예외를 처리하며, 예외에 부모-자식 관계 있는 경우
// AFTER: Java의 try-with-resources 사용
// AutoCloseable을 구현한 리소스 클래스
class MyResource implements AutoCloseable {
public void doWork() throws IOException {
System.out.println("주요 로직 실행 중...");
throw new IOException("주요 작업 실패!");
}
@Override
public void close() throws SQLException {
System.out.println("리소스 정리 중...");
throw new SQLException("리소스 정리 실패!");
}
}
public class Main {
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
resource.doWork();
} catch (Exception e) {
// e는 '주요 예외'인 IOException이 됩니다.
System.err.println("메인 예외: " + e.getMessage());
// e에 첨부된 '억제된 예외'를 확인할 수 있습니다.
for (Throwable suppressed : e.getSuppressed()) {
System.err.println("억제된 예외: " + suppressed.getMessage());
}
}
}
}
예외 처리 중에 예외 발생 시, 어떤 예외를 먼저 처리할지 검토하자.
오늘 배운 것
- 알고리즘
- swea 3499 퍼펙트 셔플
- 시뮬레이션
내일 할 일
- 포트폴리오 내용 복기