Java Checked Exception / Unchecked Exception

2SEONGA·2025년 2월 7일
2

Java

목록 보기
9/13

Java 는 에러를 자바 프로그램 입장에서의 에러 발생 근원(Source)에 따라 2가지로 구분

  • 자바 프로그램 “외부”에서 발생하는것 : (Need to be) Checked Exception

    • 충분히 예상가능한 에러이기에, 콕 집어 복구가 꼭 필요한 예외 (처리를 강제) + 제어 가능
  • 자바 프로그램 “내부 로직”에서 발생하는것 : Unchecked Exception
    - (블랙박스) 어떤 상황에서 발생되는지 예측할 수 없어, 어떻게 복구해야할지 전혀 알 수 없다. + 그 때마다
    - 그래서 로그를 잘 남겨야한다. 그게 Unchecked Exception 처리의 근본이자 원칙
    - 대다수가 (Unchecked) Exception 처리를 했다하면 로그도 안남기고 심지어는 먹어버리는 실수

    “인생으로 치면 어떤 상황이 발생할지 모르기에, 인생 중 모든 경우의 수를 대처할 수 없다.”


1. 프로그램 “외부”에서 발생 : (Need to be) Checked Exception

충분히 예상가능한 에러이기에, 콕 집어 복구가 꼭 필요한 예외

  • 에러 처리 했는지 여부를 컴파일 시간에 검증 : 여느 컴파일 에러가 그렇듯 개발 시 IDE 에서 빨간색으로 표기

”파일을 읽을 때, 파일이 존재하지 않을 때에 대한 대비가 필요합니다.
제발 처리하시고 컴파일하세요.”

  • FileNotFoundException (FileInputStream 에서 Throwing)
    • ex ) 파일을 읽을 때, 존재하지 않을 수 있다.
    • Try-Catch : 메서드 내에서 직접 처리
    private static void checkedExceptionWithTryCatch() {
        File file = new File("not_existing_file.txt");
        try {
            FileInputStream stream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    • Throws : 넘겨서 다른 메서드에서 처리하도록 이관
    private static void checkedExceptionWithThrows() {
        File file = new File("not_existing_file.txt");
        FileInputStream stream = new FileInputStream(file);
    }

[많이 쓰이는 Checked Exception]

  • IOException : 이용자는 충분히 이상한 걸 입력할 수 있다.
  • SQLException : 데이터베이스 접속은 충분히 갑자기 끊길 수 있다.
  • ParseException : 파싱하려는 값이 충분히 의도와 다른 값(NULL 등)이 들어있을 수 있다.

2. 프로그램 “내부 로직”에서 발생 : Unchecked Exception

에러가 어떤 상황에서 발생될지 예측할 수 없기에, 어떻게 복구해야할지 전혀 알 수 없다.

  • 런타임 시간에 에러 처리 : 그래서 자바 프로그램 동작 시 로직에서 에러가 발생하면,
    • 왜 발생했는지 log 로 꼭 표기하여, 어디에서 문제가 발생했는지 추론 혹은 디버깅할 수 있도록
    • Stacktrace : 어디에서 발생했습니까? = Call Stack
    • log : 힌트 혹은 이슈를 추론하기에 도움이 될만한 요소

“RuntimeException 발생 시 원인이 너무 다양하기에 로그Stacktrace 를 남겨 셜록 홈즈를 부릅시다.”

  • NullPointerException
    - ex ) 정말 알 수 없는 모종의 이유로 (셜록 홈즈가 필요하다) 특정 값이 NULL 이 되어있을 수 있다.
    private static void uncheckedExceptionWithTryCatch(String str) {
      try {
    		    str = str.toUpperCase(); // str 로 건네받은 파라미터가 null 일 수 있다.
    		    System.out.println(str);
      } catch (NullPointerException e) {
          e.printStackTrace();
      }
    }

  • 일반적으로 많이 쓰이는 Unchecked Exception
    • ArithmeticException : 나눌때 사용할 값이 변수라면, + - 등 모종의 이유로 0 이 될 수 있다.
    • ArrayIndexOutOfBoundsException : 배열의 길이가 모종의 이유로 바뀌어 접근불가능할 수 있다.
    • RuntimeException : Java 개발 시 가장 많이 사용되는 Unchecked Exception
    • 자바 프로그램 내에선 정말 다양한 이유로 예상하지 못한 에러가 발생할 수 있다.
      • 아무리 예상치 못한 에러라 할지라도, 어느 정도 범주화를 할수는 있다.
        다양한 상황을 개발자 나름 예측하여 우리가 처리하기 위한 커스텀 Exception 을 만들 수 있다.

“Java 를 잘하는 개발자는 (Runtime)Exception 처리를 잘하는 개발자이다.“

  • Exception 처리를 잘한다는 건 매 로직에서 발생할만한 에러, 상황들을 예지할 수 있단 뜻
  • Exception 처리를 잘하는 개발자란?
    1. 상황 “범주”에 맞춰 Custom Exception 정의
    2. 적합한 곳에서, 어떤 조건에 적합한 Custom Exception 발행(Throw 최초 발행)
    3. 중간 어딘가에서 적합한 처리 2가지 : Throws vs Try-Catch

다중 예외 처리와 커스텀 에러 처리

다중 예외 처리

  • Java 에서의 다중 예외 처리
try {
		// ...
} catch (IllegalArgumentException | IndexOutOfBoundsException error) {

} catch (FileNotFoundException e) {

} catch (IOException e) {

} catch (Exception e) {

}
  • JavaScript 에서의 다중 예외 처리
try {
		// ...
} catch (error) {
	  if (error instanceof TypeError) {

	  } else if (error instanceof ReferenceError) {

	  } else if (error instanceof SyntaxError) {

	  } else if (error instanceof RangeError) {

	  } else {

	  }
}

Custom Exception Class 를 만들어놓았다면, instanceof 를 통해 클래스 타입 분류

try {
		// ...
} catch (error) {
	  if (error.name === "TypeError") {

	  } else if (error.name === "ReferenceError") {

	  } else if (error.name === "SyntaxError") {

	  } else if (error.name === "RangeError") {

	  } else {

	  }
}

Custom Exception 을 프로퍼티로 분류하도록 했다면, 프로퍼티를 통해 타입 분류


커스텀 에러 처리

  • Java 에서의 다중 예외 처리 (사용자 정의 예외 타입)
class CustomException extends RuntimeException {
		private String type;
		private String code;
		public CustomException(String type, String code, String message) {
				super(message);
				this.type = type;
				this.code = code;
		}
}

추가로 Java 의 Exception 에는 어떤 값들이 들어있을까?

try {
		// ...
} catch(RuntimeException e) {
	  System.out.println(e.getCause());
	  System.out.println(e.getMessage());
	  System.out.println(e.getStackTrace());
	  e.printStackTrace();
}
  • Javascript 에서의 커스텀 에러 (사용자 정의 예외 타입)
class CustomError extends Error {
		// type;
		// code;
	  constructor(type, code. message) {
		    super(message);
		    this.type = type;
		    this.code = code;
	  }
}

추가로 Javascript 의 Error 에는 어떤 값들이 들어있을까?

try {
		testfunction() // 존재하지 않는 함수를 호출하였을때
} catch(err) {
	  alert(err.name);    // ReferenceError
	  alert(err.message); // testfunction is not defined
	  alert(err.stack);   // ReferenceError: testfunction is not defined at ... (호출 스택)
}

[여러 계층에서 Exception 발생 시 처리 방법]
1. 한곳에서 다 처리하기
2. 중간에 받아서 다시 넘기기 (Exception 타입 변경)
3. 중간에서 받아서 처리하기 (의도적 먹어버림)


3. 언제 Unchecked Exception 와 Checked Exception 를 사용할까?

  • 복구 가능한 조건에 대해 체크된 예외를 사용하고 / 프로그래밍 오류에 대해서는 런타임 예외를 사용
    • 복구 가능한 조건 : 자바 프로그램 외부에서 발생했기에 제어 가능하다.
    • 프로그래밍 오류 : 자바 프로그램 내부에서 발생한것이고, 왜 발생한것인지 알 수 없다.

하지만 라이브러리에서 사용을 강제하는게 아닌 이상에야 일반적으로 Checked Exception 은 사용하지 않는다.

4. Exception 예외처리를 잘 다룬다는것의 의미는 무엇인가?

얼마나 예외처리 Exception 을 잘 다루는지가 능력있는 개발자인지 여부를 가른다.

  1. 계층을 잘 나눈다 : Java 의 예를 들면 Repository - Service - Controller 계층으로 나눈다거나
  2. 예외 종류를 잘 나눈다 : Enum 을 통해 다양한 케이스를 커버하는 것
profile
(와.. 정말 Chill하다..)

0개의 댓글