프로잭트를 진행할 때 예외처리를 많이 사용했지만, 깊이 있게 공부하지 않은 것 같아 정리를 한번 해보려고합니다 !
❓예외 처리란 ?
예외 처리란 프로그램 실행 흐름상 오류가 발생했을 때 그 오류를 대체하는 방법입니다.
에러(Error) : 메모리 부족이나 스택오버플로우와 같이 일단 발생하면 복구할 수 없는 심각한 오류
예외(Exception) : 인자값 Null에러 NPE(NullPointException)가 발생하더라도 수습이 가능한 덜 심각한 오류
예외 계층
자바는 프로프로그램 실행 중에 발생할 수 있는 예상치 못한, 즉 예외(Exception)를 처리하기 위한 메커니즘을 제공합니다.
이는 프로그램의 안정성과 신뢰성을 높이는 데 중요한 역할을 합니다.
자바의 예외 처리는 try, catch, finally, throw, throws 키워드를 사용하며, 아래와 같이 예외 처리용 객체들을 제공합니다.
Exception은 애플리케이션 로직에서 사용할 수 있는 실질적인 최상위 예외입니다. Exception과 그 하위 예외는 모두 컴파일러가 체크하는 체크예외이고, RuntimeException은 예외로합니다.
RuntimeException은 컴파일러가 체크하지 않는 언체크 예외입니다. 언체크 예외를 런타임 예외라고 많이 부릅니다.
체크 예외와 언체크 예외(런타임 예외)
체크 예외는 발생한 예외를 개발자가 명시적으로 처리해야합니다. 그렇지 않으면 컴파일 오류가 발생합니다.
언체크 예외는 개발자가 발생한 예외를 명시적으로 처리하지 않아도 된다는 차이가 있습니다.
예외 처리 방식
체크 예외
체크 예외를 처리할 수 있는 방식은 두 가지가 있습니다.
첫 번째로는 throw로 발생 시간 에러를 try, catch를 통해 에러가 발생한 부분에서 바로 처리하는 방법이 있고, 두 번째로는 발생한 예외(Exception)을 예외가 발생하는 메서드에 throws을 선언해주는 것입니다.
throws를 통해 예외 처리를 진행할 경우 해당 로직에서 처리를 하는 것이 아닌 해당 메서드를 호출한 곳으로 예외를 던질 수 있습니다.
(이후 예외 처리는 호출한 곳에서 해결해야합니다.)
간단한 예제를 통해 살펴보겠습니다 !
// throws를 통해 호출한 곳으로 예외를 던지는 방법
public class Client{
public void connect() throws Exception {
throw new Exception();
}
}
// try, catch를 통한 예외 처리 방법
public void callCatch() {
Client client = new Client();
try {
client.connect();
} catch (Exception e) {
//예외 처리 로직
}
}
위 예제와 같이 try, catch와 thorows를 통해 예외 처리를 할 수 있습니다.
언체크 예외
언체크 예외는 말 그대로 컴파일러가 예외를 체크하지 않는다는 뜻을 의미합니다. 언체크 예외는 체크 예외와 기본적으로 동일하지만 예외를 던지는 throws를 선언하지 않고, 생락할 수 있다는 차이점이 있습니다. 생략한 경우 자동으로 예외를 던집니다.
체크 예외의 경우 처리할 수 없는 예외를 밖으로 던지려면 항상 throws 예외를 선언해야 하지만, 언체크 예외는 이 부분을 생략할 수 있다는 장점이 있지만 언제크 예외에도 단점이 존재합니다.
언체크 예외는 개발자가 실수로 예외를 누락할 수 있습니다. 반면 체크 예외는 컴파일러를 통해 예외 누락을 잡아줄 수 있습니다.
finally
cry, catch를 통해 예외 처리를 진행할 경우 cry구문 중간에 예외를 만났을 경우 코드가 마무리되지 못한채 로직이 종료됩니다.
이러한 경우 꼭 수행해야할 로직을 수행하지 못할 경우가 발생할 수 있는데 이런 문제를 해결하기 위해 자바는 어떤 경우라도 반드시 호출되는 finally 기능을 제공합니다.
정리하면 정상 흐름일 때도 finally 흐름이 제공되고, 예외(catch)일 경우에도 finally가 제공되고, 예외가 던져졌을 때도 finally가 제공됩니다. 즉, finally 블럭은 반드시 호출됩니다. 따라서 주로 try에서 사용한 자원을 해제할 때 주로 사용합니다.
간단한 예제를 살펴보고 넘어가겠습니다 !
public class Client{
public void connect() throws Exception {
throw new Exception();
}
public void disconnection {
System.out.println("연결종료");
}
}
public void callCatch() {
Client client = new Client();
try {
client.connect();
} catch (Exception e) {
//예외 처리 로직
} finally {
client.disconnection();
}
}
try-with-resources
애플리케이션에서 외부 자원을 사용하는 경우 반드시 외부 자원을 해제해야합니다. 따라서 finally 구문을 반드시 사용해야합니다.
try에서 외부 자원을 사용하고, try가 끝마녀 외부 자원을 반납하는 패턴이 반복되면서 자바에서는 Try with resources라는 편의 기능을 자바에서 도입했습니다. 이름 그대로 try에서 자원을 함께 사용한다는 뜻힙니다. 여기서 자원은 try가 끝나면 반드시 종료해서 반납해야 하는 외부 자원을 뜻합니다.
try-with-resources를 사용하려면 먼저 AutoCloseable 인터페이스를 구현해야합니다.
packege java.lang;
public interface AutoCloseable {
void close() throws Exception;
}
java.lang 패키지에 있는 인터페이스를 구현한 뒤 close 메서드를 오버라이드하면 try가 끝나는 시점에 close() 메서드가 자동으로 호출됩니다. 자원 반납 또는 필요한 로직이 있을 경우 오버라이드한 close 메서드에서 정의하면 됩니다.
아래와 같이 try-with-resources 구문을 사용할 수 있습니다.
try (Resource resource = new Resource()) {
// 리소스를 사용하는 코드
}
정리
예외 처리가 늘어날 수록 throws를 통해 처리해야할 예외들이 많아집니다. 체크 예외의 이런 문제점으로 인해 최근 라이브러리들은 대부분 언체크 예외(런타임 예외)를 사용한다고합니다.
그렇다고 모든 예외를 언체크 예외를 사용하는 것이 아닌 필요한 예외는 throws를 통해 예외를 던질 수 있습니다. 그리고 처리할 수 없는 예외는 예외를 공통으로 처리하는 부분을 만들어 해결할 수 있습니다 !
'프로그래밍 > Java' 카테고리의 다른 글
[Java, 자바] Mybatis Map foreach로 반복하기 (0) | 2024.09.10 |
---|---|
[Java, Spring] @ControllerAdvice, @RestControllerAdvice란 ? (5) | 2024.09.01 |
[Java, 자바] 중첩 클래스와 내부 클래란 ? (1) | 2024.07.29 |
[Java, Spring] Logging, @Slf4j란 ? (0) | 2024.07.29 |
[Java, Spring] application.properties란 ? (0) | 2024.07.29 |
개발의 모든 것 !
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!