JAVA - 예외 처리

이상해씨·2022년 7월 30일
0

웹 풀스택(JAVA)

목록 보기
10/54

✔예외 처리(Exception Handling)

1. 에러(Error)와 예외(Exception)

  • 에러와 예외 : 어떤 원인에 의해 오동작하거나 비정상적으로 종료되는 경우.
    • 에러(Error) : 메모리 부족, stack overflow와 같이 일단 발생하면 복구할 수 없는 상황. (심각도 높음)
      • 프로그램의 비정상적 종료를 막을 수 없음. -> 디버깅 필요.
    • 예외(Exception) : 읽으려는 파일이 없거나 네트워크 연결이 안되는 경우 등 수습될 수 있는 비교적 상태가 약한 것들. (심각도 낮음)
      • 프로그램 코드에 의해 수습될 수 있는 상황.
  • 예외 처리(Exception Handling) : 예외 발생 시 프로그램의 비정상 종료를 막고 정상적인 실행 상태를 유지하는 것.
    • try~catch~finally : 예외의 감지 및 예외 발생시 동작할 코드 작성
  • 예외 클래스의 계층
    • Checked Exception : 예외에 대한 대처 코드가 없으면 컴파일 진행 실패.
    • Unchecked Exception(RuntimeException 하위 클래스) : 예외에 대한 대처 코드가 없더라도 컴파일 진행 성공. (하지만 실행시 예외가 발생하므로 try~catch 필요.)

2. 예외 처리(Exception Handling)

  • try ~ catch : 예외 처리 기법
    • 예외를 처리하여 프로그램이 정상적으로 동작하도록 하는 역할.
      • 예외 처리는 가능한 구체적으로 진행.
    • 어떠한 예외도 발생하지 않는 경우 catch 블록을 거치지 않고 다음 문장 실행.
    • finally : 예외 발생 여부와 상관없이 언제나 실행하는 블록
      • 주요 목적 : try 블록에서 사용한 리소스 반납.(자원 정리를 위해 사용.)
        • 생성한 시스템 자원을 반납하지 않으면 resource leak 발생 가능.(파일 입출력은 운영체제에서 관리.)
try{
	// 예외가 발생할 수 있는 코드
	// 예외 발생시 JVM이 해당 [throw  new XXException].
}catch (XXException e){
	// 던진 예외를 받음
	// 적당한 catch 블록을 만나지 못하면 예외처리 실패.
	// 예외가 발생했을 때 처리할 코드.
}finally{
	// try ~ catch 구문 이후 언제나 실행되는 블록.
}
  • Exception 객체의 정보 활용
    • Throwable의 주요 메서드
      • public String getMessage() : 발생된 예외에 대한 구체적인 메시지 반환.
      • public Throwable getCause() : 예외의 원인이 되는 Throwable 객체 또는 null 반환.
      • public void printStackTrace() : 예외가 발생된 메서드가 호출되기가지의 메서드 호출 스택 출력.
        • 디버깅 수단으로 주로 사용.
        • 프로그램 정보가 그대로 노출되므로 디버깅으로만 사용하고 실제 제품 배포때는 이 메서드를 막은 상태로 출시해야한다.
  • 다중 Exception Handlig 기법
    • 하나의 try 블록에 여러 개의 catch 블록 추가 가능.
    • 다중 catch 문장 작성 순서 유의 사항 : 작은 범위(자식)에서 큰 범위(조상)순으로 정의.
      • JVM이 던진 예외는 catch 문장을 찾을 때 다형성 적용.
      • 상위 타입 예외가 먼저 선언되는 경우 뒤에 등장하는 catch 블록은 동작할 기회가 없음.
        • Unreachable catch block for Exception
      • 상속 관계가 없는 경우는 무관
    • 발생하는 예외들을 하나로 처리하기 : Exception 사용.
      • 예외 상황별 처리의 어려움.
      • 가급적 예외 상황별로 처리하는 것 권장.
    • 심각하지 않은 예외 세분화하여 처리하는 것도 낭비
      • '|' 연산을 이용해 하나의 catch 구문에서 상속관계가 없는 여러 개의 exception 처리
      • (ex) XXException | OOException e
    • 계층을 이루는 예외의 처리 : 상속 관계를 고려하여 처리.
  • try - with ~ resources : JDK 1.7 이상에서 리소스 자동 close 처리.
    • 단, 해당 객체들이 AutoCloseable interface를 구현해야 한다.
      • FileInputStream -> InputStream -> Closeable -> AutoCloseable
      • 각종 I/O Stream, socket, connection, ...
    • 해당 객체는 try 블록에서 다시 할당될 수 없다.
try(리소스_타입1 res1 = 초기화; 리소스_타입2 res2 = 초기화; ...){
	// 예외 발생 코드
}catch(Exception e){
	// Exception Handling 코드
}

2. throws

  • throws 키워드 : 처리해야할 예외 위임.
    • method에서 처리해야 할 하나 이상의 예외를 호출한 곳으로 전달(처리 위임)
      • 예외가 없어지는 것이 아니라 단순히 전달하는 것.
      • 예외를 전달받음 메서드는 다시 예외 처리의 책임 발생.
      • 처리하려는 예외의 조상 타입으로 throws 처리 가능.
  • checked exception throws 처리 위임.
// checked exception
// 해당 예외를 전달받은 곳에서 처리해야한다.
// throws 키워드가 없다면 예외 처리를 하라는 오류가 발생.
void testMethod() throws Exception1, Exception2{
	// 예외 발생 코드
}

void methodCaller(){
	try{
		testMethod();
	}catch (Exception e){
		// 예외 처리 코드
	}
}
  • runtime exception(unchecked exception) throws 처리 위임.
// runtime exception(unchecked exception)
// trhows하지 않아도 전달 되지만 결국 try~catch를 통해 처리해야한다.
void testMethod(){
	// 예외 발생 코드
}

void methodCaller(){
	try{
		testMethod();
	}catch (Exception e){
		// 예외 처리 코드
	}
}
  • 로그 분석과 예외의 추적
    • Throwable의 printStackTrace는 메서드 호출 스택 정보 조회 가능.
      • 최초 호출 메서드에서부터 예외 발생 메서드까지 스택 정보 출력.
    • 예외 종류, 예외 원인, 디버깅 출발점. 등 확인.
  • 메서드 재정의와 throws
    • 메서드 재정의시 조상 클래스 메서드가 던지는 예외보다 큰(조상) 예외를 던질 수 없다.
      • 부모가 치지 않은 사고를 자식이 칠 수 없다.

✔사용자 정의 예외

  • 사용자 정의 예외 : API에 정의된 exception 이외에 필요에 따라 사용자 정의 예외 클래스 작성
    • 대부분 Exception 또는 RuntimeException 클래스 상속받아 작성.
      • checked exception 활용 : 명시적 예외 처리 또는 throws 필요.(코드 복잡, but 처리 누락 등의 오류 가능성 저하)
      • runtime exception 활용 : 묵시적 예외 처리 가능.(코드 간결, but 처리 누락 등의 오류 가능성 상승)
    • 장점
      • 객체의 활용 : 필요한 추가 정보, 기능 활용 가능.
      • 코드의 재사용 : 동일한 상황에서 예외 객체 재사용 가능.
      • throws 메커니즘 이용 : 중간 호출 단계에서 return 불필요.
  • 시스템의 RuntimeException은 처리의 대상이기보다는 디버깅의 대상.
profile
후라이드 치킨

0개의 댓글