전체 보기

[백기선 자바] 예외 처리

작성일자
2023/07/27
태그
SUB PAGE
프로젝트
백기선 자바
책 종류
1 more property

[자바 라이브 스터디] 9주차 - 예외 처리

목표) 자바의 예외 처리에 대해 학습하세요.
9
issues

1. Exception과 Error의 차이는?

프로그램 에러
정의) 프로그램 실행 중 오작동을 하거나 비정상적으로 종료되게 하는 원인
종류) 발생 시점에 따라 구분
컴파일 에러 : 컴파일 시 발생
런타임 에러 : 실행 시 발생
논리적 에러 : 실행은 되지만, 의도와 다르게 동작
예외와 에러
정의) 자바는 런타임 에러를 예외와 에러 두 가지로 구분함
종류)
예외(Exception)
정의) 프로그램 코드에 의해 수습될 수 있는 다소 미약한 오류
에러(Error)
정의) 프로그램 코드에 의해 수습될 수 없는 심각한 오류
예시) 메모리 부족, 스택오버플로우

2. 자바가 제공하는 예외 계층 구조

정의) 자바에선 예외와 에러를 클래스로 정의함
예외 클래스 계층도
특징)
모든 클래스의 조상은 Object 클래스이므로 예외(Exception)와 에러(Error) 클래스 역시 Object 클래스의 자손들임

3. RuntimeException과 RE가 아닌 것의 차이는?

정의) RuntimeException 클래스와 그 자손 클래스들을 RuntimeException 클래스들이라 하고, RuntimeException클래스들을 제외한 나머지 클래스들을 Exception 클래스들 이라 하자.
Exception 클래스와 RuntimeException클래스 중심의 상속 계층도
차이점)
RuntimeException 클래스들
정의) 프로그래머의 실수로 발생하는 예외
예시) ArrayIndexOutOfBoundException, NullPointerException, ClassCastException, ArithmeticException
Exception 클래스들
정의) 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
예시) FileNotFOundException, ClassNotFoundException, DataFormatException

4. 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)

정의) 프로그램 실행 시 발생할 수 있는 예외에 대비한 코드 작성
목적) 프로그램의 비정상 종료를 막고, 정상적인 실행 상태를 유지하게 함
발생한 예외 처리 못하면, 프로그램은 비정상적으로 종료되며 처리되지 못한 예외는 JVM의 예외처리기(UncaughtExceptionHandler)가 받아서 예외의 원인을 화면에 출력함
방법)
try-catch문 이용
구조)
try { // 예외가 발생할 가능성이 있는 코드 } catch (Exception1 e1) { // Exception1이 발생했을 때, 이를 처리하기 위한 코드 } catch (Exception2 e2) { // Exception2가 발생했을 때, 이를 처리하기 위한 코드 } catch (ExceptionN eN) { // ExceptionN이 발생했을 때, 이를 처리하기 위한 코드 }
Java
복사
특징)
예외의 종류와 일치하는 단 한 개의 catch 블럭만 수행됨
발생한 예외의 종류와 일치하는 catch 블럭이 없으면 예외는 처리되지 않음
괄호 생략 불가함
finally 블럭을 덧붙여 예외의 발생 여부에 상관 없이 실행되어야 할 코드 포함시킬 수 있음
실행 순서는 예외가 발생한 경우엔 try → catch → finally 순, 예외가 발생하지 않은 경우엔 try → finally 순
try-with-resources문 이용
구조)
try ( // 여기서 할당 받은 자원은 블록 수행 이후 자동으로 반환됨 ) { // 예외가 발생할 가능성이 있는 코드 } catch (Exception e) { // Exception 처리 }
Java
복사
특징)
try-catch문의 변형으로 JDK1.7부터 추가됨
자원 해제를 자동으로 해줌
단, 모든 객체가 자동으로 반환되는 것은 아니고 AutoCloseable 인터페이스를 구현한 클래스만 자동으로 반환됨
입출력과 관련된 클래스 사용할 때 유용함
원래) finally 구문 사용
public static void main(String args[]) throws IOException { FileInputStream is = null; BufferedInputStream bis = null; try { is = new FileInputStream("file.txt"); bis = new BufferedInputStream(is); //... do something } catch (IOException e) { // 에러처리 } finally { // 어떤 경우에도 반드시 자원을 닫아야함 if (is != null) is.close(); if (bis != null) bis.close(); } }
Java
복사
변경) try-with-resources 구문 이용
public static void main(String args[]) { try ( FileInputStream is = new FileInputStream("file.txt"); BufferedInputStream bis = new BufferedInputStream(is) ) { //... do something } catch (IOException e) { // 에러처리 } }
Java
복사
메서드에 예외 선언
구조)
void method() throws Exception1, Exception2 ... ExceptionN { // 메서드의 내용 }
Java
복사

5. 커스텀한 예외 만드는 방법

평소에 아래와 같은 방식으로 만듦
ErrorCode Enum
@Getter @AllArgsConstructor public enum ErrorCode { // 공통 예외 BAD_REQUEST_PARAM(HttpStatus.BAD_REQUEST, "잘못된 요청입니다."), // USER 예외 NOT_FOUND_USER(HttpStatus.NOT_FOUND, "해당 유저를 찾을 수 없습니다."); private final HttpStatus status; private final String error; }
Java
복사
ErrorResponse Dto
@Getter @Builder public class ErrorResponse { private final String status; private final String error; public static ResponseEntity<ErrorResponse> toResponseEntity(CustomException e) { ErrorCode errorCode = e.getErrorCode(); return ResponseEntity .status(errorCode.getStatus()) .body( ErrorResponse.builder() .status(errorCode.getStatus().name()) .error(errorCode.getError()) .build() ); } }
Java
복사
CustomException
@Getter public class CustomException extends RuntimeException { private final ErrorCode errorCode; public CustomException(ErrorCode errorCode) { super(errorCode.getError()); this.errorCode = errorCode; } }
Java
복사
CustomExceptionHandler
@Slf4j @RestControllerAdvice public class CustomExceptionHandler { @ExceptionHandler protected ResponseEntity<ErrorResponse> handleCustomException(CustomException e) { return ErrorResponse.toResponseEntity(e); } }
Java
복사