예외 처리

정민교·2023년 2월 16일
0

📒프로그램 오류

예외처리 란 프로그램의 비정상적인 종료를 방지하고 정상적인 실행상태를 유지하기 위한 처리를 말한다.
발생 시점에 따라 컴파일 에러, 런타임 에러로 나눈다.

📌컴파일 에러

컴파일 할 때 발생하는 에러.
주로 오타, 문법적 오류로 인해 발생한다.

📌런타임 에러

실행 시에 발생하는 에러
실행 시 발생할 수 있는 프로그램 오류를 에러예외 두 가지로 구분한다.

  • 에러: 복구하기 어려운 수준의 심각한 오류(메모리 부족, 스택오버플로우 등)
  • 예외: 코드 수정 등을 통해 수습이 가능한 오류

📒예외 클래스 상속 계층도

실행 시 발생할 수 있는 오류가 클래스(Exception, Error)로 정의되어 있다.

모든 예외와 에러 클래스는 Throwable 클래스로부터 확장되고 모든 예외의 최고 조상은 Exception 클래스다.
예외 클래스는 두 그룹으로 나눌 수 있다.

📌일반 예외 클래스(Exception)

RuntimeException 클래스와 그 하위 클래스를 제외한 모든 Exception 클래스와 그 하위 클래스들.
컴파일러가 실행 전에 예외 처리를 확인하기 때문에 checked 예외 라고 부른다.
프로그램 사용자의 실수로 발생하는 경우가 많다.

📌실행 예외 클래스(RuntimeException)

RuntimeException 클래스와 그 하위클래스들.
컴파일러가 예외 처리 코드 여부를 검사하지 않기 때문에 unchecked 예외 라고 부른다.
개발자의 실수로 발생하는 경우가 많다.

📒try-catch-finally 문

예외가 발생할 가능성이 있는 코드들을 try 블럭 에 작성하며, 발생한 예외를 처리하는 코드들을 catch 블럭 에 작성한다.
catch 블럭 은 여러 개 작성할 수 있으며, 발생한 예외의 종류와 일치하는 catch 블럭 하나만 실행된다.

  • try 블럭 에서 예외가 발생한 경우
    예외가 발생하면 발생한 예외에 해당하는 클래스의 인스턴스가 생성된다.
    발생한 예외 종류와 일치하는 catch 블럭 을 찾아서(instanceof 연산자를 통해 검사) 실행하고, 이후 전체 try-catch 문 을 빠져나가고 다음 문장들을 실행한다.
    일치하는 catch 블럭 을 찾지 못하면 예외는 처리되지 못한다.
  • try 블럭 에서 예외가 발생하지 않은 경우, catch 블럭 은 실행되지 않고 try-catch 문 을 빠져나가 다음 문장들을 실행한다.

발생한 예외를 처리하지 못하면 프로그램은 비정상 종료되고, 처리되지 못한 예외(uncaught exception)JVM의 예외처리기(UncauthExceptionhandler) 가 받아서 예외 원인을 화면에 출력한다.

finally 블럭 은 예외 발생 여부와 상관없이 무조건 실행된다.

📒printStackTrace(), getMessage()

예외가 발생했을 때 생성되는 예외 인스턴스는 발생한 예외에 대한 정보가 담겨 있다.

  • pringStackTrace()
    예외가 발생했을 때의 호출 스택에 있던 메서드의 정보와 예외 메세지를 화면에 출력한다.
  • getMessage()
    발생한 예외 인스턴스에 저장된 예외 메세지를 얻을 수 있다.

📒멀티 catch 블럭

여러 catch 블럭| 기호를 사용하여 하나의 catch 블럭 으로 합칠 수 있다.

try {
  ...
} catch (ExceptionA | ExceptionB e) {
  ...
}

연결된 예외 클래스가 조상과 자손의 관계라면 컴파일 에러가 발생한다.

📒예외 발생시키기

throw 키워드를 사용하여 예외를 발생시킬 수 있다.

Exception e = new Exception("의도적으로 발생시킨 에외");
throw e;
//혹은
throw new Exception();

Exception 인스턴스를 생성할 때, 생성자에 String을 인자로 전달해 예외 메세지를 저장할 수 있다.

📒메서드에 예외 선언(예외 전가)

메서드 선언부에 throws 키워드를 사용하여 메서드 내에서 발생할 수 있는 예외를 적어준다.
여러 예외가 발생한다면 ,로 구분해서 여러 개의 예외를 선언할 수 있다.

void method() throws Exception {
  ...
}

위와 같이 예외를 선언하면 Exception 클래스는 모든 예외 클래스의 상위 클래스이기 때문에 하위 클래스 타입의 예외 클래스들이 모두 포함된다.

메서드의 선언부에 예외를 선언하는 것은 해당 메서드(예외가 발생할 수 있는 메서드)를 호출하는 메서드에게 예외를 전달하여 예외 처리를 떠맡기는 것이다.

📒사용자 정의 예외 만들기

Exception 클래스 또는 RuntimeException 클래스를 상속하여 사용자 정의 예외 클래스를 만든다.

class MyException extends Exception {
  private final int ERR_CODE;
  
  MyException(String msg, int errCode) {
    super(msg); // 조상인 Exception클래스의 생성자를 호출
    ERR_CODE = errCode;
  }
}

Exception 클래스를 상속 하면 checked 예외 로 반드시 예외 처리를 해야 하지만, RuntimeException 클래스를 상속 하면 unchecked 예외 로 예외 처리를 선택적으로 할 수 있다.

📒예외 되던지기

예외가 발생할 가능성이 있는 메서드에서 try-catch 문 을 사용해서 예외를 처리하고, catch 블럭 에서 throw 키워드를 사용하여 예외를 다시 발생시켜 이 메서드를 호출한 메서드에게 예외를 넘겨 호출한 메서드에서도 예외를 처리하도록 하는 방법이다.

try-catch 문을 사용해서 예외를 처리함과 동시에 메서드 선언부에 발생할 예외를 선언해주어야 한다.

📒연결된 예외

예외 A가 예외 B를 발생시켰다면, A를 B의 원인 예외 라고 한다.
initCause() 메서드의 인자로 특정 예외를 전달하여 원인 예외로 등록할 수 있다.
Exception 클래스의 조상인 Throwable 클래스에 정의되어 있기 때문에 모든 예외에서 사용 가능하다.

Throwable initCause(Throwable cause) //지정한 예외를 원인 예외로 등록
Throwable getCause() // 원인 예외를 반환

여러가지 예외를 하나의 큰 예외로 묶어서 다루기 위해서 예외를 연결하기 위해서다.

profile
백엔드 개발자

0개의 댓글