본문 바로가기

Server Programming/BackEnd Project

30일차 - 자바. 예외처리

반응형

예외처리

  • 컴파일 에러
  • 런타임 에러
  • 예외는 처리 가능한 오류
    • 의미적 제약을 위반했을 때 JVM이 프로그램에게 예외라는 에러가 발생했다고 알린다.
    • 예외가 발생했을 때 프로그래머가 원하는 방향으로 움직이도록 하는 것을 예외처리라고 말한다.

Exception

  • 제어의 비지역 이동
    • 자바에서 예외가 발생하면 JVM은 예외를 던지고, 발생 지점에서 프로그래머가 지정한 위치로 이동한다.
    • 프로그램의 흐름을 문맥이라고 하는데 이러한 제어의 흐름을 주어진 문맥의 외부로 이동시키고, 미리 선언된 지점에서부터 수행
    • 예외, 조건, Continuation은 비지역 제어 구문의 일반적인 예이다.

 

Exception 처리 키워드

  • try
  • catch
  • finally
  • throw
  • throws

  • 예외 처리 용도
    • 정상 종료
    • 예외 내용 보고
    • 무시하고 계속 실행
    • 대안적인 결괏값을 대입
  • JVM이 메인 메서드 실행 -JVM이 예외를 던진다. -예외 발생시 log 찍어서 로그를 남겨두는 것이 중요하다.

예외처리 try-catch 구문

  • 예외 클래스에 따라 처리 수행하기 위해 여러 개의 catch블럭을 사용한다.
  • System.exit()제외하고 return문이 존재하더라도, finally 블럭 실행 순서 뒤로 이동시킨다.
  • 일반적으로 finally 블럭에는 DB or Network Connection close 같은 자원 해제 명령과 같은 문장을 작성한다.
  • try 블록 안에는 예외 관련되지 않은 코드는 제외하도록 한다.
  • JVM에서 예외처리 되지 않았을 경우에 예외 관련 정보와 stack trace를 출력하고 프로그램을 강제종료시킨다.
  • 일반적으로 stack trace는 로깅 처리를 통해 로그 파일에 기록하는데, 모니터링 툴에서 예외를 수집해서 확인하기도 한다.

Throw 키워드

  • 메소드의 throw 타입으로 정의된 타입과 그 타입의 하위 클래스 타입으로 예외 생성해서 명시적으로 예외를 던질 때 사용
    • throw의 타입은 throws 타입과 그 하위 자손들만 가능
  • 강제적으로 예외를 발생시켜서 비즈니스 오류로 인한 예외를 던짐으로 프로그램 흐름을 제어할 수 있다.
  • 런타임이 아닌 컴파일 타임에 오류를 확인해 양질의 코드 확보 가능

 

  • 같은 시점일 경우 같고, 시점이 다르면 다르다
    • catch블럭이 잡은 시점에서의 printStackTrace()
    • 처리하지 않았을 때는 예외 발생 시점

Call Stack Mechanism (예외의 전파)

  • (RuntimeException과 그 자손들의 경우 예외 처리가 선택이므로)
  • 만약 예외가 발생한 메소드에서 처리하지 않으면, 메소드를 호출한 곳으로 throw 된다.
  • 만약 메인메서드까지 예외처리하지 않으면 비정상종료

 

Method Overriding 예외 처리

  • 하위 클래스에서 상위 클래스 메서드 오버라이딩시 상위클래스 메서드에 throws절이 정의되어있으면 반드시 하위클래스에서 동일한 타입의 exception clalss나 하위 타입의 exception class type으로 정의해야만 한다.
  • 즉 상위 클래스 메소드의 throws Exception type보다 상위 타입으로는 선언할 수 없다.
  • 오버라이딩 조건 :  예외처리 개수가 같거나 적어야한다.
    -> 단, 상위클래스 메서드의 throws절의 예외 클래스 타입에 대해 여러개의 동일하거나 또 다른 하위 예외 클래스 타입으로 정의해야 한다.

 

사용자 정의 예외

  • Exception이라고 적는게 이름 규칙
  • 일반적으로 에러메시지를 생성자의 매개변수로 전달해 조상클래스의 생성자를 이용해 에러 메시지를 출력한다.
package ch12;

public class ExceptionUserDefined {
    public void connect(String serverName) throws ServerTimedOutException {
        boolean success;
        int port = 80;

        success = open(serverName, port);
        if(!success) {
            throw new ServerTimedOutException("연결할 수 없습니다", port);
       }
    }
    public boolean open(String serverName, int port){
        // method body
        return false;
    }
    public void findServer(){
        try {
            connect("ProductServer");
        } catch (ServerTimedOutException se) {
            System.out.println("서버 접속시간 초과, 대채 서버 시도");
            try {
                connect("AlterProductServer");
            } catch (ServerTimedOutException rse) {
                System.out.println("Error : " + rse.getMessage() +
                        "포트에 연결 " + rse.getPort());
            }
        }
    }

    public static void main(String argsp[]){
        ExceptionUserDefined e = new ExceptionUserDefined();
        e.findServer();
    }
}

 

package ch12;

public class ServerTimedOutException extends Exception {
    private int port;

    public ServerTimedOutException(String message, int port) {
        // Exception 클래스에 예외 메시지 전달을 위해 super를 이용하여 상위 생성자 호출
        super(message);
        this.port = port;
    }
    public int getPort() {
        return port;
    }
}

 

catch 블럭 동작 방식

  • 첫번째 캐치블럭부터 순서대로 내려가는데, 일치하는 캐치블럭이 없으면 예외처리를 하지 않는다.
  • printStackTrace(), getMessage()와 같은 메서드를 일반적으로 사용한다.
  • 일반적으로 실무에서는 logger.error(e)를 통해 로그로 남긴다.

 

스프링에서 예외처리 순서

  • 브라우저 요청
  • 스프링 디스패처서블릿
  • 애플리케이션 영역
  • 컨트롤러
  • 서비스
  • DB
    어디서 예외가 발생하든 예외를 클라에게 제공할 수 있도록 가공

 

스프링에서의 예외처리 방식

: 예외핸들러, 컨트롤러 어드바이스 등으로 상태별로 관리한다.

 

예외 유형

  • Checked Exception
    • RunException 및 Error를 제외한 Throwable 클래스를 직접 상속하는 클래스는 컴파일 타임에 체크되는 예외로 예외 처리 필수
  • Unchecked Exception
    • 예외 처리 선택
    • 개발자의 실수로 일반적으로 예외처리를 수행하지 않는다. (코드가 복잡해지므로)

 

Null Safety방식

  • if문으로 not null 체크
  • Optional으로 체크
  • 일반적으로 널포인터예외처리는 사용하지 않는다.

 

다중 catch블럭 (Java 7등장)

  • 각 예외 타입 클래스를 '|'기호로 구분해서 연결한다.
  • 처리내용이 같으면 1개의 캐치블럭으로 2개 이상의 예외를 처리한다.

 

중첩 try-catch 블럭

  • try블록 내에 try블록을 중첩으로 사용하는 것
  • 블록 일부가 오류를 일으킴으로 전체 블록이 또 다른 오류를 일으키는 경우가 발생할 경우에 예외처리를 중첩해서 사용한다.
  • 즉 catch 블럭에서 예외처리 하는 과정에서 예외가 발생하면 catch블럭안에 try-catch블럭을 중첩해서 사용

 finally 블럭

  • 자원 반납 등의 cleanup 코드 수행을 위해 사용
  • 반드시 실행 되어야하는 명령문을 배치한다.
  • catch블럭을 통해 catch가 안될때 finally 블럭에 자원을 반납하거나 반드시 실행되어야 하는 코드를 추가한다.
반응형

'Server Programming > BackEnd Project' 카테고리의 다른 글

31일차 - TIL  (0) 2023.01.12
30일차 - TIL  (0) 2023.01.11
29일차 - TIL  (0) 2023.01.10
28일차- 자바. 인터페이스와 내부클래스  (0) 2023.01.09
28일차 -TIL  (0) 2023.01.09