일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- exception re-throwing
- 빨간폴더
- 인텔리제이
- 깃베쉬
- arrays메서드
- throw e
- 설치에러
- getMessage()
- 인텔리제이물음표파일
- 자바클래스가 안보일때
- printStackTrace()
- 파일을 읽을 수 없을때
- 이클립스
- checked예외
- mark directory as
- 포트충돌
- chained exception
- 빨간파일
- 예외 발생
- POST요청
- 멀티 catch 블럭
- mvc project 생성
- 스프링 mvc프로젝트가 안뜰때
- source root
- 색상에 따른 상태
- 예외발생
- 소스루트설정
- unchecked예외
- 사용자 정의 예외
- 예외처리
- Today
- Total
프로그래밍 스티치
예외 되던지기(exception re-throwing) 본문
예외 되던지기(exception re-throwing)
한 메서드에서 발생할 수 있는 예외가 여럿인 경우, 몇개는 try-catch문을 통해서 자체적으로 처리하고, 그 나머지는 선언부에 지정하여 호출한 메서드에서 처리하도록 함으로써, 양쪽에서 나눠서 처리되도록 할 수 있다.
이것은 예외를 처리한 후에 인위적으로 다시 발생시키는 방법을 통해서 가능한데, 이것을 '예외 되던지기(exception re-throwing)'라고 한다.
이 방법은 하나의 예외에 대해서 예외가 발생한 메서드와 이를 호출한 메서드 양쪽 모두에서 처리해줘야 할 작업이 있을 때 사용된다. 이 때 주의할 점은 예외가 발생할 메서드에서는 try-catch문을 사용해서 예외처리를 해줌과 동시에 메서드의 선언부에 발생할 예외를 throws에 지정해줘야 한다는 것이다.
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
System.out.println("main메서드에서 예외가 처리되었습니다.");
}
} // main메서드의 끝
static void method1() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e; // 다시 예외를 발생시킨다.
}
} // method1메서드의 끝
위의 예시에서 알 수 있듯이 method1()과 main메서드 양쪽의 catch블럭이 모두 수행되었음을 알 수 있다. method1()의 catch블럭에서 예외를 처리하고도 throw문을 통해 다시 예외를 발생 시켰다. 그리고 이 예외를 main 메서드에서 한 번 더 처리한 것이다.
+주의할점!
반환값이 있는 return문의 경우, catch블럭에도 return문이 있어야 한다. 예외가 발생했을 경우에도 값을 반환해야하기 때문이다.
연결된 예외(chained exception)
한 예외가 다른 예외를 발생시킬 수도 있다. 예를 들어, 예외 A가 예외 B를 발생시켰다면, A를 B의 '원인 예외(cause exception)'라고 한다. 예시를 살펴보자
void install() throws InstallException
try{
startInstall(); // SpaceException 발생
copy();
} catch { SpaceException e) {
InstallException ie = new InstallException("설치중 예외발생"); // 예외발생
ie.initCause(e); // InstallException의 원인 예외를 SpaceException으로 지정
throw ie; // InstallException을 발생시킨다.
} catch (MemoryException me) {
'''
먼저 InstallException을 생성한 후에, initCause()로 SpaceException을 InstallException의 원인 예외로 등록한다. 그리고 'throw'로 이 예외를 던진다.
initCause()는 Exception클래스의 조상인 Throwable클래스에 정의되어 있기 때문에 모든 예외에서 사용 가능하다.
원인 예외에 관한 문법
Throwable initCause(Throwable cause) : w지정한 예외를 원인 예외로 등록
Throwable getCause() : 원인 예외를 반환
발생한 예외를 그냥 처리하면 될 텐데, 원인 예외로 등록해서 다시 예외를 발생시키는 이유는 무엇일까?
바로, 여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위해서이다.
또 다른 이유는, checked예외를 unchecked예외로 바꿀 수 있도록 하기 위해서이다. checked예외로 예외처리를 강제한 이유는 프로그래밍 경험이 적은 사람도 보다 견고한 프로그램을 작성할 수 있도록 유도하기 위함이었는데, 지금은 자바가 처음 개발되던 1990년대와 컴퓨터 환경이 많이 달라졌다. 그래서 checked예외가 발생해도 예외를 처리할 수 없는 상황이 하나둘 발생하기 시작했다. 이럴 때 할 수 있는 일이라곤 그저 의미없는 try-catch문을 추가한느 것 뿐인데, checked예외를 unchecked예외로 바꾸면 예외처리가 선택적이 되므로 억지로 예외처리를 하지 않아도 된다.
static void startInstall() throws SpaceException, MemoryException {
if(!enoughSpace()) // 충분한 설치공간이 없다면!
throw new SpaceException("설치할 공간이 부족합니다")
if(!enoughMemory()) // 충분한 메모리가 없다면!
throw new MemoryException("t메모리가 부족합니다");
}
위의 예제는 checked예외의 예시인데 이것을 unchecked예외로 변경해보면
static void startInstall() throws SpaceException {
if(!enoughSpace()) // 충분한 설치공간이 없다면!
throw new SpaceException("설치할 공간이 부족합니다")
if(!enoughMemory()) // 충분한 메모리가 없다면!
throw new RuntimeException(new MemoryException("메모리가 부족합니다"));
} // 메모리 익셉션이 런타임익셉션의 원인 예외가 된것!
이렇게 MemoryException을 예외처리를 선택적으로 바꿀 수 있다! 이렇게 변경하면 선언부에 MemoryException을 선언하지 않아도 된다.
참고로 위의 코드에서는 initCause()대신 RuntimeException의 생성자를 사용했다
RuntimeException 생성자의 문법
RuntimeException(Thorwable cause) // 원인 예외를 등록하는 생성자
'JAVA > 예외처리' 카테고리의 다른 글
finally블럭 (0) | 2022.02.09 |
---|---|
메서드에 예외 선언하기 (0) | 2022.02.08 |
예외 발생시키기 (0) | 2022.02.08 |
멀티 catch 블럭 (0) | 2022.02.08 |
try-catch문에서의 흐름 (0) | 2022.02.08 |