Java 예외 처리 심화: try-catch-finally와 리소스 관리
Java 예외 처리 마스터하기
Java try-catch-finally 메커니즘과 try-with-resources가 어떻게 견고하고 에러 없는 코드 작성을 돕는지 탐구합니다.
try…catch 구문은 Java에서 우아한 에러 처리의 핵심. 런타임 문제 예측하고 크래시 없이 대응 가능하게 합니다.
표준 문법:
try { // 예외 발생 가능 코드 } catch (ExceptionType e) { // 예외 처리 }
try 블록에 예외 발생 가능 코드 배치. 예외 발생 시 제어는 일치하는 catch 블록으로 점프, 적절 대응 가능.
예제: ArithmeticException 처리
class Main { public static void main(String[] args) { try { int result = 5 / 0; System.out.println("This line is never reached."); } catch (ArithmeticException e) { System.out.println("Caught: " + e.getMessage()); } } }
출력
Caught: / by zero
여기서 0으로 나누기 시 ArithmeticException 발생. catch 블록이 잡아 프로그램 크래시 방지.
팁: finally 블록 실행만 관심 있으면 catch 블록 생략 가능, 하지만 catch는 선행 try 없인 존재 불가.
Finally 블록 사용
finally 절은 예외 발생 여부와 무관하게 실행 보장:
class Main { public static void main(String[] args) { try { int result = 5 / 0; } finally { System.out.println("Cleanup actions run here."); } } }
출력
Cleanup actions run here. Exception in thread "main" java.lang.ArithmeticException: / by zero at Main.main(Main.java:4)
finally 블록은 try 블록 후 실행, 예외가 정상 흐름 방해해도 실행.
Try, Catch, Finally 결합
가장 견고한 코드는 세 절 모두 사용해 에러 처리, 보고, 리소스 정리. 파일 처리 예제:
import java.io.*; class ListOfNumbers { private int[] list = {5, 6, 8, 9, 2}; public void writeList() { PrintWriter out = null; try { System.out.println("Attempting to write to file."); out = new PrintWriter(new FileWriter("OutputFile.txt")); for (int i = 0; i < 7; i++) { out.println("Value at: " + i + " = " + list[i]); } } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } finally { if (out != null) { System.out.println("Closing PrintWriter"); out.close(); } else { System.out.println("PrintWriter not opened."); } } } } class Main { public static void main(String[] args) { new ListOfNumbers().writeList(); } }
출력
Attempting to write to file. Exception: Index 5 out of bounds for length 5 Closing PrintWriter
배열 경계 위반이 예외 트리거, 캐치되어 보고됨. finally 블록이 PrintWriter 닫아 리소스 누수 방지.
모범 사례: 정리 로직(파일, 소켓, DB 연결 닫기) 항상 finally 블록에 배치.
참고: finally는 JVM 종료(System.exit()), finally 내 예외, 스레드 급작스런 종료 시 실행 안 될 수 있음.
여러 예외 타입 처리
단일 try에 여러 catch 절 연결 가능, 각기 특정 예외 맞춤:
class ListOfNumbers { private int[] arr = new int[10]; public void writeList() { try { arr[10] = 11; } catch (NumberFormatException e) { System.out.println("NumberFormatException: " + e.getMessage()); } catch (IndexOutOfBoundsException e) { System.out.println("IndexOutOfBoundsException: " + e.getMessage()); } } } class Main { public static void main(String[] args) { new ListOfNumbers().writeList(); } }
출력
IndexOutOfBoundsException: Index 10 out of bounds for length 10
런타임이 첫 catch 시도, 매치 안 되면 다음으로 진행해 매치 찾을 때까지 반복.
단일 Catch로 여러 예외 잡기 (Java 7+)
Java 7에서 단일 catch에 예외 타입 결합 도입, 중복 감소:
try { // 위험 코드 } catch (IOException | SQLException ex) { // 통합 처리 }
다른 예외가 동일하게 처리될 때 이 기능 사용.
Try-With-Resources로 자동 정리
Try-with-resources 문은 AutoCloseable 구현 리소스 자동 닫기:
try (PrintWriter out = new PrintWriter(new FileWriter("OutputFile.txt"))) { // 리소스 사용 } catch (IOException e) { // I/O 에러 처리 }
리소스가 괄호 내 선언되어 블록 종료 시 자동 닫힘, 예외 발생해도 동일.
더 깊은 통찰은 공식 Java 문서 try-with-resources 참조.