☕Java: Exception (2) 사용자정의 예외, 강제 예외발생, 예외의 변환
강의 수강 중 작성한 노트에서 내용을 발췌, 이응수 강사님 강의 의 노트와 이미지를 참조하고 있습니다.
스스로 이해를 위해 직접 쓴 문장들의 경우 정확성이 떨어질 수 있다는 점 참고 부탁드립니다.
사용자정의 예외, 강제 예외발생, 예외의 변환
📌 사용자정의 예외클래스
-
Checked
예외클래스 만들기: Exception 클래스를 상속받는다.- 이는 예외처리를 강제하는 예외클래스를 정의하는 것이다.
-
Unchecked
예외클래스 만들기: RuntimeException 클래스를 상속받는다.- 이는 예외처리를 강제하지 않는 예외클래스를 정의하는 것이다.
- 현재는 대부분 Unchecked 사용자정의 예외클래스를 선호한다.
-
작성방법
- 생성자 메소드를 정의할 때 부모클래스의 생성자메소드를 호출하려는 super() 메소드를
반드시 사용해야 한다. - 오류 정보에 필요한 멤버변수를 추가할 수 있다.
- 생성자 메소드를 정의할 때 부모클래스의 생성자메소드를 호출하려는 super() 메소드를
- 작성 목적
- 애플리케이션에 최적화된 예외를 정의할 수 있다. (자바에서 제공해주는 것과 달리)
- 애플리케이션에서 발생하는 예외의 종류를 단순화시킬 수 있다.
(지정하고자 하는 사용자정의 예외클래스 타입으로 통일시켜 발생시킬 수 있으므로) - 예외의 종류를 단순화시킬 수 있기 때문에 최종단계에서 예외에 대한 일괄처리가 단순해진다.
- 다양한 오류정보를 표현할 수 있다.
- 오류에 대한 더 정확한 내용을 전달할 수 있다. 문법적인 문제 뿐만이 아니라, 업무 로직상의 문제 또한 메세지에 내용을 적어 예외로 발생시킬 수 있다.
- 예외의 처리는 한 곳에서 일괄적으로 할 것이기 때문에 처리를 하는 것보다 적절한 예외를 발생시키는 것이 더 중요하다.
public class HtaException extends RuntimeException {
private static final long serialVersionUID = 9175601348921699186L;
public HtaException(String message) {
super(message);
}
public HtaException(String message, Throwable cause) {
super(message, cause);
}
}
💡 serialVersionUID
Serializable
인터페이스의 구현 클래스에는serialVersionUID
가 정의되어있어야 한다. 없다고 컴파일 에러가 생기지는 않지만, 이는 클래스의 식별번호로서 네트워크로 객체를 주고받을 때 주로 사용된다.
- 정의하는 목적
- 설계도에 대한 빠른 식별
- 다시 컴파일하더라도 식별번호가 달라지지 않도록 해서 같은 설계도를 다른 것으로 인식하지 않도록 함.
💡 예외클래스 생성의 의미
Exception
클래스는
- String값을 받아서 메시지로 저장하는 생성자
- Throwable 구현 객체를 받아서 원인이 되는 예외를 저장하는 생성자 를 가지고 있다.
Exception
또는RuntimeException
클래스를 상속받은사용자정의 예외클래스
또한 자바 라이브러리의 다른 예외클래스처럼
메시지와 원인이 되는 예외 객체를 저장할 수 있게 하기 위하여 정의한다.
이 생성 과정을 통해 예외의 내용이 정해지는 것이 아니다.
이는 기본적으로 예외 객체를 만들고, 내용을 저장해 사용할 수 있도록 하는 클래스의 생성 방법이다.
📌 강제 예외발생
- 업무로직상의 오류가 있는 경우(비밀번호 불일치, 잔액부족, 로그인 실패 등) 예외를 강제로 발생시켜서 해당 기능을 호출한 측에게 오류가 발생했음을 알리는 것이다.
- throw 키워드를 사용한다.
- throw로 발생시킨 Unchecked 예외객체는 따로 처리하지 않으면 다음의 호출하는 주체로 위임된다. (처리가 강제되지는 않고, 떠넘겨지는 것이다.)
📌 예외의 변환
- 실제 발생한 예외 대신 사용자정의 예외를 발생시키는 것
- throw 키워드를 사용한다.
- throw new 예외클래스(오류메세지, 실제발생한예외)
- 사용자 정의 예외객체와 실제 발생한 예외(원인이 된 예외=cause)객체에 대한 정보가 모두 출력된다.
- 여러 종류의 예외를 처리하는 것보다 하나의 사용자정의 예외만 처리하도록 하는 것이 목적이다.
- 예외의 종류 단순화
- 어떤 부분에서 에러가 났는지 파악하기 쉬워진다.
- 메소드에서 발생하는 다양한 예외를 catch블록에서 잡고, 대신 사용자정의 예외를 발생시킬 수 있다.
- 또다시 사용자정의 예외는 처리할 필요가 없도록 unchecked로 작성한다.
- cause 인자값을 통해 실제 발생한 예외에 대한 정보를 전달할 수 있다.
- 사용자정의 예외 클래스를 부모 클래스와 여러 자식 클래스로 나누어, catch는 부모 클래스로-하나의 사용자정의 예외클래스 타입으로- 정의하고 throw문에서는 자식 클래스들을 이용해 경우별로 구체적으로 나눌 수 있다.
💡 예외의 변환
사용자정의 예외클래스는unchecked
로 한다. checked라면 또 이 클래스에서 예외처리를 해야 하므로. 여러 예외를 같은 ‘사용자정의 예외클래스’로 묶어서 전달시키는 것이 목적이다.
try {
예외발생이 예상되는 코드 // SQLException 이 발생예상됨
} catch (SQLException e) {
throw new 사용자정의예외클래스("메세지", e);
}
public class CommonUtils {
public static int stringToInt(String text) {
if (text == null) {
// 사용자 정의 예외객체 발생시키기
throw new HtaException("text는 null일 수 없습니다.");
}
if (text.isBlank()) {
// 사용자 정의 예외객체 발생시키기
throw new HtaException("Text가 빈 문자열이거나 공백문자입니다.");
}
try {
int value = Integer.parseInt(text);
return value;
} catch (NumberFormatException ex) {
// 예외의 변환
// Integer.parseInt()메소드가 발생시킨 NumberFormatException을 catch에서 잡고, 대신 HtaException을 발생시키기
throw new HtaException("text에 숫자가 아닌 문자가 포함되어 있습니다.", ex);
}
}
}
💡 예외를 발생시키는 것 자체가 메소드 블록 내의 ‘빠른 종료’를 시킨다.
따라서 값을 반환하는 메소드에서 값 반환 대신 예외를 발생시켜도 컴파일 오류는 아니다.
그러나 if문 내에서 예외를 발생시킨다면, if문이 false일 경우-반환값이 없을 경우-도 고려해야 한다.
(if문 내에서 예외 발생, if문 밖에서 아무것도 반환하지 않는다면 오류)
📌 계층적 프로그래밍에서의 예외 발생
어플리케이션 개발 시 표현계층 / 서비스계층 / 영속화계층
세 계층으로 나누어 개발하는데,
업무로직을 수행하는 서비스계층
(Service 클래스)에서 수행과정 중 업무로직에 위배되는 상황이 발생하면 예외를 발생시킨다.
영속화계층
(DAO클래스, Repository클래스)는 특별한 업무로직을 수행하지 않고 업무로직 수행에 필요한 데이터엑세스 작업을 지원한다.
발생한 예외는 최종적인 위치인 표현 계층
(Controller 클래스) 에서 일괄적으로 처리한다. 그 전까지는 계속해서 위임시킨다.
Author And Source
이 문제에 관하여(☕Java: Exception (2) 사용자정의 예외, 강제 예외발생, 예외의 변환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yoondgu/Java-Exception-2-사용자정의-예외-강제-예외발생-예외의-변환저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)