Effective Java : 아이템9. 완벽공략
- 프로그래밍 언어/JAVA
- 2023. 4. 5.
들어가기 전
이 글은 백기선님의 이펙티브 자바 강의를 복습하며 작성한 글입니다.
아이템 9.완벽 공략
- p48, 자바 퍼즐러 예외 처리 코드의 실수
- p49, try-with-resources 바이트 코드
이 장에서는 위 두 가지에 대한 완벽 공략을 공부했다.
자바 퍼즐러
자바 퍼즐러는 책이다. 자바 퍼즐러에는 아래와 같은 코드가 있는데, 이렇게 작성된 코드는 안전한 코드인지 아닌지에 대해서 많은 사람들이 헷갈려한다. 이 부분은 자원을 중첩으로 사용하고 해제하는데 있어서 try - finally 문의 약점을 보여준다.
이렇게 했을 때 안전한 코드일까? 이 코드는 안전하지 않은 코드다. 왜냐하면 다음 상황이 발생할 수 있기 때문이다.
out.close()를 하다가 발생하는 에러는 catch 절에서 IOException만 잡는다. 만약 out.close()에서 RuntimeException이 발생하게 된다면 뒷쪽에 있는 코드 in.close() 는 수행되지 않는다.
만약 try - finally를 이용해서 안전하게 자원을 종료하고 싶다면 아래 코드처럼 nested로 작성해주어야 한다. 아래 코드에서는 out.close() 실행 도중 예상치 못한 에러가 나와도 outer의 finally 절로 넘어가고, 이곳에서 in.close()를 정상적으로 호출해 줄 수 있게 된다.
static void copy(String src, String dst) throws IOException {
FileInputStream in = new FileInputStream(src);
try {
FileOutputStream out = new FileOutputStream(dst);
try {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}finally {
out.close();
}
}finally {
in.close();
}
}
가장 좋은 방법은 try-with-resources 구문을 사용하는 것이다. 아래처럼 깔끔하게 고쳐서 사용할 수 있게 된다.
static void copy(String src, String dst) throws IOException {
try(FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dst)){
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
try-with-resources 바이트 코드
그렇다면 try-with-resource는 어떻게 구성되어 있길래, 자동으로 close()가 호출되고 예외가 보존되어서 나오는 것일까? try-with-resource는 build를 하게 되면 특정한 바이트 코드로 바뀌게 되는데, 이것이 이런 기능들을 구현해준다. 다음 순서를 따른 후에 바이트 코드를 살펴본다.
- gradle clean
- gradle build
위 명령어를 수행하면 Target 디렉토리에 생성된 바이트 코드를 살펴볼 수 있다. 코드는 어떻게 바뀌었을까? 아래는 기본적으로 작성한 자바코드다. 이 자바 코드가 바이트 코드로 바뀐 것을 살펴보자.
바뀐 자바코드는 다음과 같다. 여기서 살펴볼 점은 var5 + addSuppressed() 메서드다.
- var5는 가장 첫번째 발생한 에러를 catch 절에서 잡은 것이다.
- var4는 두번째 발생한 에러다. 두번째 발생한 에러는 var5.addSuppressed()를 통해서 추가된다.
정리
- try - finally로 중첩 자원을 정리한다면, nested로 정리하는 것이 가장 안전하다. (try-with-resources를 사용하라)
- 첫번째 발생한 에러가 다른 에러에 의해서 없어지는 것을 원하지 않는다면, 첫번째 발생한 에러에 addSuppressed()를 이용해서 에러를 추가 구성하는 형태로 작성한다.
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
Effective Java : 아이템18. 상속보다는 컴포지션을 사용하라 (0) | 2023.04.09 |
---|---|
Effective Java : 아이템17. 완벽공략 (0) | 2023.04.09 |
Effective Java : 아이템16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라. (0) | 2023.04.05 |
Effective Java : 아이템15. 클래스와 멤버의 접근 권한을 최소화하라. (0) | 2023.04.04 |
Effective Java : 아이템8. 완벽공략 (0) | 2023.04.03 |