STUDY/Java

[Java] 예외 (Exception)

ofijwe 2024. 11. 1. 18:02
반응형

📒 예외의 처리

1️⃣ 에러와 예외

  • 어떤 원인에 의해 오동작 하거나 비정상적으로 종료되는 경우
  • exception handling(예외 처리)란?
    • 예외 발생 시 프로그램의 비 정상 종료를 막고 정상적인 실행 상태를 유지하는 것
    • 예외의 감지 및 예외 발생 시 동작할 코드 작성 필요

2️⃣ 예외 클래스의 계층

  • checked exception → 예외에 대한 대처 코드가 없으면 컴파일이 진행되지 X
  • unchecked exception → 예외에대한 코드가 없더라도 컴파일은 진행됨

3️⃣ Exception handling 기법

  • try{} catch() {}
  • public class SimpleException { public static void main(String[] args) { int[] intArray = { 10 }; try { System.out.println(intArray[2]); } catch (ArrayIndexOutOfBoundsException e) { // 사고처리 System.out.println(e.getMessage()); e.printStackTrace(); } System.out.println("프로그램 종료합니다."); } }
  • Throwable의 주요 메서드
    • public String getMessage() - 발생된 예외에 대한 구체적인 메시지 반환
    • public Throwable getCause() - 예외의 원인이 되는 Throwable 객체 또는 null을 반환
    • public void printStackTrace() - 예외가 발생된 메서드가 호출되기까지의 메서드 호출 스택을 출력 / 주로 디버깅의 수단으로 사용

4️⃣ try-catch문 흐름

  • try-catch문 흐름
    • try 블록에서 예외 발생 시 JVM이 해당 Exception 클래스의 객체 생성 후 던짐(throw)
    • 던져진 exception을 처리할 수 있는 catch 블록에서 받은 후 처리
    • 정상적으로 처리되면 try-catch블록을 벗어나 다음 문장 진행
  • try 블록에서 어떠한 예외도 발생하지 않을 경우
    • catch 문을 거치지 않고 try-catch블록의 다음 흐름 문장 실행
  • Checked Exception 처리
    • 처리하지 않으면 컴파일 불가 : Checked Exception
  • public class CheckedExceptionHandling { public static void main(String[] args) { // TODO: 다음에서 발생하는 예외를 처리해보자. // 예외 처리를 위해 try-catch문 사용 try { Class<?> myclass = Class.forName("com.ssafy.day09.a_basic.SimpleException"); // Unhandled exception type ClassNotFoundException 라는 에러 발생 System.out.println(myclass.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } // END System.out.println("프로그램 정상 종료"); } }

5️⃣ 다중 exceptino handling

  • try 블록에서 여러 종류의 예외가 발생할 경우
    • 하나의 try 블록에 여러 개의 catch 블록 추가 가능
    • 예외 종류별로 catch 블록 구성
    • 처리될 catch 문장을 찾을 때는 다형성이 적용됨
  • 다중 catch 문장 작성 순성 유의 사항
    • 상위 타입의 예외가 먼저 선언되는 경우 뒤에 등장하는 catch 블록 동작 기회 X
      • Unreachable catch block for Exception
      • 상속 관계가 없는 경우는 무관
    • 상속 관계에서는 작은 범위(자식)에서 큰 범위(조상)순으로 정의
  • FileNotFoundException의 상속 관계
    • java.lang.Object → java.lang.Throwable → java.lang.Exception → java.lang.IOException → java.lang.FileNotFoundException

📒 try ~ catch ~ finally

1️⃣ try ~ catch ~ finally 구문을 이용한 예외 처리

  • finally는 예외 발생 여부와 상관없이 언제나 실행
    • 중간에 return을 만나는 경우도 finally 블록을 먼저 수행 후 리턴 실행
  • 주요 목적 → try 블록에서 사용한 리소스 반납
  • 생성한 시스템 자원 반납 필요
    • 반납하지 않을 시 장래 resource leak 발생 가능 → 반드시 close 처리
  • 지저분할 수 밖에 없는 finally 블록
    • close 메서드 자체가 IOException 유발 가능
    • FileInputStream 생성자에서 IOException 발생 시 fileInput은 null인 상황

2️⃣ try ~ with ~resources

  • 리소스의 자동 close 처리
    • try(리소스_타입1 res1 = 초기화; 리소스_타입2 res2 = 초기화; …) {} catch() {}
  • try 선언문에 선언된 객체들에 대해 자동 close 호출(finally 역할)
    • 해당 객체들이 AutoCloseable interface를 구현할 것
    • 해당 객체는 try 블록에서 다시 할당될 수 X → final 변수로 간주
  • 주의점
    • 확장된 rtywithresources 사용시 문장에 하나 이상의 catch 또는 finally 필요
    • 자동 생성되는 코드들이 실제로 어떻게 동작되는지 정확히 알아야 함.
    • trywithresources문장은 nested try 블록을 구성
  • 단순 VS 확장 trywithresources
    • 단순 → 그냥 쓰고 close만 할 경우 최적

📒 throws 활용

1️⃣ throws 키워드를 통한 처리 위임

  • method에서 처리해야 할 하나 이상의 예외를 호출한 곳으로 전달 (처리 위임)
    • 단순 전달(예외 없어지는 것 X)
    • 예외 전달받은 메서드는 다시 예외처리의 책임 발생
    • 처리하려는 예외 조상 타입으로 throws 처리 가능
  • checked exception과 throws
    • checked exception → 반드시 try~catch or throws 필요
    • 필요한 곳에서 try~catch 처리
  • runtime exception과 throws
    • runtime exception은 throws 하지 않아도 전달됨.
    • but, 결국 try~catch로 처리해야 함.
  • 로그 분석과 예외의 추적
    • Throwable의 printStackTrace는 메서드 호출 스택 정보 조회 가능
      • 최초 호출 메서드부터 예외 발생 메서드까지 스택 정보출력
    • 확인해야할 정보
      • 예외 종류 →어떤 예외인지
      • 예외 원인 → 예외 객체의 메시지는 무엇인지
      • 디버깅 출발점 → 어디서 발생했는지
  • throws의 목적과 API 활용
    • API가 제공하는 메서드는 사전 예외 발생 가능을 선언부에 명시 (예외 발생 - 예외 전파)
    • 프로그래머가 예외를 처리하도록 강요 (상황 인지 - 적절한 예외 처리)

2️⃣ 메서드 재정의와 throws

  • 메서드 오버라이드 5가지 role
    • 이름, 파라미터, 리턴타입, 접근제한자, 예외처리
  • 메서드 재정의 시 조상 클래스 메서드가 던지는 예외보다 부모예외를 던질 수 X
    • 즉, 부모가 치지 않은 사고를 자식이 칠 수 X

3️⃣ 예외 변환

  • 하위 계층에서 발생한 예외는 상위 계층에 맞는 예외로 바꿔서 던져야 함.
  • 쉽게 말해, 배송 측에서 받은 문제사항을 추가로 가공해주고 새로 가공된 걸 고객에게 전달해주는 것
  • Exception Chaining
    • 하위 계층에서 발생한 예외 정보가 상위 계층의 예외를 디버깅하는데 유용할 경우 사용
    • 하위 계층의 예외를 원인으로 상위 계층에서 예외를 발생

📒 사용자 정의 예외

1️⃣ 사용자 정의 예외

  • API에 정의된 exception 외 필요에 따라 사용자 정의 예외 클래스 작성
  • 대부분 Exception or RuntimeException 클래스 상속받아 작성
    • checked exception 활용
      • 명시적 예외 처리 or throws 필요
      • 코드 복잡 → but, 오류 발생 가능성 낮음
    • runtime exception 활용
      • 묵시적 예외 처리 가능
      • 코드 간결 → but, 예외 처리 누락 가능성 발생
  • 사용자 정의 예외 장점
    • 객체 활용
      • 필요한 추가정보, 기능 활용 가능
    • 코드 재사용
      • 동일한 상황에서 예외 객체 재사용 가능
    • throws 메커니즘 이용
      • 중간 호출 단계에서 return 불필요
반응형