finally블록
try-catch문 끝에 선택적으로 덧붙여 사용
예외의 발생여부에 관계없이 실행되어야 할 코드를 작성
|
1
2
3
4
5
6
7
|
try {
// 예외가 발생할 가능성 있는 문장
} catch (Exception e) {
// 예외처리를 위한 문장
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야 할 문장
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class FinallyTest3 {
static void method1() {
try {
System.out.println("method1()메소드가 실행중");
return; // 메소드 종료
} catch(Exception e) {
e.printStackTrace();
} finally {
System.out.println("method1()의 finally블럭 실행!"); // 무조건
}
}
public static void main(String[] args) {
FinallyTest3.method1();
System.out.println("method1()의 수행을 마치고 main메소드");
}
}
|
cs |
출력
method1()메소드가 실행중
method1()의 finally블럭 실행!
method1()의 수행을 마치고 main메소드
try-with-resources문
입출력과 관련된 클래스를 사용할 때 유용,
입출력에 사용되는 클래스 중에서 사용한 후에 꼭 닫아 줘야 하는 것들이 있음
그래야 사용했던 자원(resources)이 반환되기 때문
괄호()안에 객체를 생성하는 문장을 넣으면, 이 객체는 따로 close()를 호출하지 않아도,
try블럭을 벗어나면 자동적으로 close()가 호출됨
try-with-resources문에 의해 자동으로 객체의 close()가 호출될 수 있으려면,
클래스가 AutoCloseable이라는 인터페이스를 구현한 것이어야 함
|
1
2
3
4
|
public interface AutoCloseable {
void close() throws Exception;
}
|
cs |
|
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
package exception;
// 사용자정의 예외
class WorkException extends Exception {
WorkException(String msg) { super(msg); }
}
// 사용자정의 예외
class CloseException extends Exception {
CloseException(String msg) { super(msg); }
}
// try-with-resources문 작성을 위한 AutoCloseable인터페이스를 구현한 임의의 클래스 작성
class CloseableResource implements AutoCloseable {
// 예외를 발생시키는 메소드, true면 예외 발생시킴
public void exceptionWork(boolean exception) throws WorkException {
System.out.println("exceptionWork("+exception+")가 호출됨!");
if(exception)
throw new WorkException("WorkException발생!");
}
@Override
public void close() throws CloseException {
// close()를 호출하면 예외발생시킴
System.out.println("close()가 호출됨");
throw new CloseException("CloseException발생!");
}
}
public class TryWithResourcesEx {
public static void main(String[] args) {
// try-with-resources문
try(CloseableResource cr = new CloseableResource()) {
cr.exceptionWork(false);
// try문 이후에 자동으로 close()메소드 실행
} catch(WorkException e) {
e.printStackTrace();
} catch(CloseException e) {
e.printStackTrace();
}
System.out.println();
try(CloseableResource cr = new CloseableResource()) {
cr.exceptionWork(true); // WorkException예외 발생
// try문 이후에 자동으로 close()메소드 실행
} catch(WorkException e) {
e.printStackTrace();
} catch(CloseException e) {
e.printStackTrace();
}
}
}
|
cs |
출력
exceptionWork(false)가 호출됨!
close()가 호출됨
exception.CloseException: CloseException발생!
exceptionWork(true)가 호출됨!
close()가 호출됨
at exception.CloseableResource.close(TryWithResourcesEx.java: 25)
at exception.TryWithResourceEx.main(TryWithResourcesEx.java: 34)
exception.WorkException: WorkException발생!
at exception.CloseableResource.exceptionWork(TryWithResourcesEx.java: 19)
at exception.TryWithResourceEx.main(TryWithResourcesEx.java: 42)
Suppressed: exception.CloseException: CloseException발생!
at exception.CloseableResource.close(TryWithResourcesEx.java: 25)
at exception.TryWithResourceEx.main(TryWithResourcesEx.java: 43)
사용자정의 예외 만들기
기존에 정의된 예외 클래스 외에 필요에 따라 새로운 예외 클래스를 정의하고 사용할 수 있음
|
1
2
3
4
5
|
class MyException extends Exception { // 사용자 예외 클래스 정의위해 Exception클래스 상속
MyException(String msg) { // Exception클래스의 생성자 호출,
super(msg);
}
}
|
cs |
|
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package exception;
// 사용자정의 예외
class SpaceException extends Exception {
SpaceException(String msg) { super(msg); }
}
// 사용자정의 예외
class MemoryException extends Exception {
MemoryException(String msg) { super(msg); }
}
public class NewExceptionTest {
// 메소드에 예외선언, 이 메소드를 호출한 메소드에서 예외 처리
static void startInstall() throws SpaceException, MemoryException {
if(!enoughSpace())
throw new SpaceException("설치할 공간이 부족해요"); // 예외 발생
if(!enoughMemory())
throw new MemoryException("메모리가 부족해요"); // 예외 발생
}
static void copyFiles() { /* 파일들을 복사하는 코드 */ }
static void deleteTempFiles() { /* 임시파일들을 삭제하는 코드 */ }
static boolean enoughSpace() {
// 설치하는데 필요한 공간이 있는지 확인하는 코드
return false;
}
static boolean enoughMemory() {
// 설치하는데 필요한 메모리공간이 있는지 확인하는 코드
return true;
}
public static void main(String[] args) {
try {
startInstall(); // 프로그램 설치에 필요한 준비를 한다
copyFiles(); // 파일들을 복사
} catch(SpaceException e) {
System.out.println("에러메세지 : " + e.getMessage());
e.printStackTrace();
System.out.println("공간을 확보한 후에 다시 설치해주세요");
} catch(MemoryException e) {
System.out.println("에러메세지 : " + e.getMessage());
e.printStackTrace();
System.gc(); // Garbage Collection을 수행해 메모리를 늘려줌
} finally {
deleteTempFiles(); // 프로그램 설치에 사용된 임시파일들을 삭제
}
}
}
|
cs |
출력
에러메세지 : 설치할 공간이 부족해요
exception.SpaceException: 설치할 공간이 부족해요
공간을 확보한 후에 다시 설치해주세요
at exception.NewExceptionTest.startInstall(NewExceptionTest.java:18)
at exception.NewExceptionTest.main(NewExceptionTest.java:38)
예외 되던지기
한 메소드에서 발생할 수 있는 예외가 여럿인 경우,
몇 개는 try-catch문을 통해서 메소드 내에서 자체적으로 처리하고,
그 나머지는 선언부에 지정하여 호출한 메소드에서 처리하도록 함으로써
양쪽에서 나눠서 처리되도록 할 수 있다
단 하나의 예외에 대해서도 예외가 발생한 메소드와 호출한 메소드, 양쪽에서 처리하도록 할 수 있음
예외를 처리한 후 인위적으로 다시 발생시키는 '예외 되던지기'를 통해서 가능함
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package exception;
public class ExceptionEx17 {
static void method1() throws Exception {
try {
throw new Exception(); // 예외 발생
} catch(Exception e) {
System.out.println("method1()에서 예외가 처리되었음");
throw e; // 다시 예외 발생시킴
}
}
public static void main(String[] args) {
try {
method1();
} catch(Exception e) {
System.out.println("main메소드에서 예외 처리되었음");
}
}
}
|
cs |
출력
method1()에서 예외가 처리되었음
main메소드에서 예외 처리되었음
연결된 예외
원인 예외 - 예외 A가 예외 B를 발생시켰다면, A를 B의 '원인 예외'라고 함
Throwable initCause(Throwable cause) 지정한 예외를 원인 예외로 등록
Throwable getCause() 원인 예외를 반환
RuntimeException(Throwable cause) 원인 예외를 등록하는 생성자
연결된 예외를 사용하는 이유는,
여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위함
|
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package exception;
// 사용자정의 예외
class InstallException extends Exception {
InstallException(String msg) { super(msg); }
}
// 사용자정의 예외
class SpaceException extends Exception {
SpaceException(String msg) { super(msg); }
}
// 사용자정의 예외
class MemoryException extends Exception {
MemoryException(String msg) { super(msg); }
}
public class ChainedExceptionEx {
public static void main(String[] args) {
try {
install();
} catch(InstallException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
// SpaceException, MemoryException예외가 발생하면 InstallException예외가 발생
// SpaceException, MemoryException예외를 하나의 큰 분류인 InstallException예외로 묶음
static void install() throws InstallException {
try {
startInstall(); // 프로그램 설치에 필요한 준비를 한다
copyFiles(); // 파일들을 복사
} catch(SpaceException se) {
InstallException ie = new InstallException("설치 중 예외발생");
ie.initCause(se); // InstallException의 원인예외를 SpaceException으로 지정
throw ie; // InstallException예외 발생
} catch(MemoryException me) {
InstallException ie = new InstallException("설치 중 예외발생");
ie.initCause(me); // InstallException의 원인예외를 MemoryException으로 지정
throw ie; // InstallException예외 발생
} finally {
deleteTempFiles(); // 프로그램 설치에 사용된 임시파일들을 삭제
}
}
// 메소드에 예외선언, 이 메소드를 호출한 메소드에서 예외 처리
static void startInstall() throws SpaceException, MemoryException {
if(!enoughSpace())
throw new SpaceException("설치할 공간이 부족해요"); // 예외 발생
if(!enoughMemory())
throw new MemoryException("메모리가 부족해요"); // 예외 발생
}
static void copyFiles() { /* 파일들을 복사하는 코드 */ }
static void deleteTempFiles() { /* 임시파일들을 삭제하는 코드 */ }
static boolean enoughSpace() {
// 설치하는데 필요한 공간이 있는지 확인하는 코드
return false;
}
static boolean enoughMemory() {
// 설치하는데 필요한 메모리공간이 있는지 확인하는 코드
return true;
}
}
|
cs |
출력
exception.InstallException: 설치 중 예외발생
at exception.ChainedExceptionEx.install(ChainedExceptionEx.java:37)
at exception.ChainedExceptionEx.main(ChainedExceptionEx.java:22)
Caused by: exception.SpaceException: 설치할 공간이 부족해요
at exception.ChainedExceptionEx.startInstall(ChainedExceptionEx.java:52)
at exception.ChainedExceptionEx.install(ChainedExceptionEx.java:34)
... 1 more
너무 꼼꼼하게 보는걸까
진도가 너무 느린거같다
잘하고 있는건지 계속 의심된다
하나하나 열심히 해보자
'아카이브 > 자바의 정석' 카테고리의 다른 글
| 9장 java.lang패키지와 유용한 클래스 20201017 (0) | 2020.10.17 |
|---|---|
| 9장 java.lang패키지와 유용한 클래스 20201014 (0) | 2020.10.14 |
| 8장 예외처리 20201009 (0) | 2020.10.09 |
| 7장 20200926 (0) | 2020.09.26 |
| 7장 20200925 (0) | 2020.09.25 |