[Java] 객체 생성과 파괴 9
EFFECTIVE JAVA 3/E 책을 공부하고 정리한 글입니다.
📖 try-finally보다는 try-with-resources를 사용하라
📌 try-finally
-
자바 라이브러리에는 close 메서드를 호출하여 직접 닫아줘야 하는 자원이 많다.
ex> InputStream, OutputStream, java.sql.Connection 등
-
자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어진다.
--> 이런 자원 중 상당수가 안전망으로 finalizer을 활용하지만, 이는 믿을만 하지 않다.
--> 전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 사용되었다.
// [코드 9-1] try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다!
static String firstLineOfFile(String path) throws IOEception {
BufferedReader br = new BufferedReader(new FileReader(path));
try{
return br.readLine();
} finally {
br.close();
}
}
- 자원을 하나 더 사용한다면 지저분해진다.
// [코드 9-2] 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!
static void copy(String src, String dst) throws IOException {
InputStream in = new FileInputStream(src);
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-finally 문을 사용한 앞의 두 코드에서 미묘한 결점이 존재한다.
-- 예외는 try블록과 finally블록 모두에서 발생할 수 있는데, 만약 기기에 물리적인 문제가 생긴다면 두 번째 예외가 첫 번째 예외를 완전히 집어삼켜 버린다.
-- 그러면 스택 추적 내역에 첫 번째 예외에 관한 정보는 남지 않게 되어 디버깅이 매우 어렵다.
-- 이를 해결하기 위해 첫 번째 예외를 기록하도록 코드를 수정할 수는 있지만 이는 코드가 매우 지저분하게 한다.
📌 try-with-resources
- try-finally의 문제점을 해결하기 위해, 자바 7 에서 try-with-resources를 제공한다.
-- 이 구조를 사용하려면 AutoCloseable 인터페이스를 구현해야 한다.
-- 이 인터페이스는 단순히 void를 반환하는 close 메서드 하나만 정의한 인터페이스 이다.
-- 자바 라이브러리와 서드파티 라이브러리들의 수많은 클래스와 인터페이스가 이미 AutoCloseable을 구현하거나 확장해뒀다.
// [코드 9-3] try-with-resources - 자원을 회수하는 최선책!
// 코드 9-1에 try-with=resources을 적용한 코드
static String firstLineOfFile(String path) throws IOException {
try(BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
// [코드 9-4] 복수의 자원을 처리하는 try-with-resources - 짧고 매혹적이다!
// 코드 9-2에 try-with-resources를 적용한 코드
static void copy(String src, String dst) throws IOException {
try(InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
-
짧고 읽기 수월하고, 문제를 진단하기도 훨씬 좋다.
-
숨겨진 예외도 스택 추적 내역에 '숨겨졌다'(getSuppressed)는 꼬리표를 달고 출력된다.
-- 자바 7에서 Throwable에 추가된 getSuppressed 메서드를 이용하면 프로그램 코드에서 가져올 수도 있다.
-
보통의 try-finally에서처럼 try-with-resources에서도 catch 절을 사용할 수 있다.
-- 이 덕분에 try 문을 더 중첩하지 않고도 다수의 예외를 처리할 수 있다.
// [코드 9-5] try-with-resources를 catch 절과 함께 쓰는 모습
static String firstLineOfFile(String path, String defaultVal) {
try(BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch(IOException e) {
return defaultVal;
}
}
📌 핵심 정리
꼭 회수해야 하는 자원을 다룰 때는 try-finally 대신 try-with-resources를 사용하자!
코드는 더 짧고 분명해지고 생성되는 예외 정보도 훨씬 유용하다.
try-with-resources로는 정확하고 쉽게 자원을 회수할 수 있다.
Author And Source
이 문제에 관하여([Java] 객체 생성과 파괴 9), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@yun12343/Java-객체-생성과-파괴-9
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
자바 라이브러리에는 close 메서드를 호출하여 직접 닫아줘야 하는 자원이 많다.
ex> InputStream, OutputStream, java.sql.Connection 등
자원 닫기는 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이어진다.
--> 이런 자원 중 상당수가 안전망으로 finalizer을 활용하지만, 이는 믿을만 하지 않다.
--> 전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 사용되었다.
// [코드 9-1] try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다!
static String firstLineOfFile(String path) throws IOEception {
BufferedReader br = new BufferedReader(new FileReader(path));
try{
return br.readLine();
} finally {
br.close();
}
}
// [코드 9-2] 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!
static void copy(String src, String dst) throws IOException {
InputStream in = new FileInputStream(src);
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블록과 finally블록 모두에서 발생할 수 있는데, 만약 기기에 물리적인 문제가 생긴다면 두 번째 예외가 첫 번째 예외를 완전히 집어삼켜 버린다.
-- 그러면 스택 추적 내역에 첫 번째 예외에 관한 정보는 남지 않게 되어 디버깅이 매우 어렵다.
-- 이를 해결하기 위해 첫 번째 예외를 기록하도록 코드를 수정할 수는 있지만 이는 코드가 매우 지저분하게 한다.
-- 이 구조를 사용하려면 AutoCloseable 인터페이스를 구현해야 한다.
-- 이 인터페이스는 단순히 void를 반환하는 close 메서드 하나만 정의한 인터페이스 이다.
-- 자바 라이브러리와 서드파티 라이브러리들의 수많은 클래스와 인터페이스가 이미 AutoCloseable을 구현하거나 확장해뒀다.
// [코드 9-3] try-with-resources - 자원을 회수하는 최선책!
// 코드 9-1에 try-with=resources을 적용한 코드
static String firstLineOfFile(String path) throws IOException {
try(BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
// [코드 9-4] 복수의 자원을 처리하는 try-with-resources - 짧고 매혹적이다!
// 코드 9-2에 try-with-resources를 적용한 코드
static void copy(String src, String dst) throws IOException {
try(InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
짧고 읽기 수월하고, 문제를 진단하기도 훨씬 좋다.
숨겨진 예외도 스택 추적 내역에 '숨겨졌다'(getSuppressed)는 꼬리표를 달고 출력된다.
-- 자바 7에서 Throwable에 추가된 getSuppressed 메서드를 이용하면 프로그램 코드에서 가져올 수도 있다.
보통의 try-finally에서처럼 try-with-resources에서도 catch 절을 사용할 수 있다.
-- 이 덕분에 try 문을 더 중첩하지 않고도 다수의 예외를 처리할 수 있다.
// [코드 9-5] try-with-resources를 catch 절과 함께 쓰는 모습
static String firstLineOfFile(String path, String defaultVal) {
try(BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch(IOException e) {
return defaultVal;
}
}
꼭 회수해야 하는 자원을 다룰 때는 try-finally 대신 try-with-resources를 사용하자!
코드는 더 짧고 분명해지고 생성되는 예외 정보도 훨씬 유용하다.
try-with-resources로는 정확하고 쉽게 자원을 회수할 수 있다.
Author And Source
이 문제에 관하여([Java] 객체 생성과 파괴 9), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yun12343/Java-객체-생성과-파괴-9저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)