반응형
예외처리
- 컴파일 에러
- 런타임 에러
- 예외는 처리 가능한 오류
- 의미적 제약을 위반했을 때 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 |