Effective Java | Item 9. try-finally보다는 try-with-resources를 사용하라
Effective Java 3/E 판을 읽고 정리한 기록입니다.
try-finally 구문
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
// 파일을 읽고 처리하는 코드
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
기존에는 자원을 해제하기 위해 try-finally 구문을 많이 사용했습니다.
위 코드는 파일을 읽기 위해 BufferedReader 를 열고,
try 블록 안에서 파일을 처리한 후, finally 블록에서 파일을 닫습니다.
하지만 위의 try-finally 구문을 사용하면 여러 단점이 존재합니다.
try-finally 구문의 단점
코드의 복잡성
BufferedReader br = null;
PrintWriter pw = null;
try {
br = new BufferedReader(new FileReader("input.txt"));
pw = new PrintWriter(new FileWriter("output.txt"));
// 파일을 읽고 쓰는 코드
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (pw != null) {
pw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
try-finally 구문은 자원을 해제하는 데 있어서 코드가 복잡해지고 가독성이 떨어집니다.
예를 들어, 여러 자원을 사용할 때 finally 블록 내에서 각각의 자원을 닫아줘야 합니다.
자원 누출 가능성
BufferedReader br = null;
PrintWriter pw = null;
try {
br = new BufferedReader(new FileReader("input.txt"));
pw = new PrintWriter(new FileWriter("output.txt"));
// 파일을 읽고 쓰는 코드
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace(); // 첫 번째 자원을 닫는 과정에서 예외 발생
}
try {
if (pw != null) {
pw.close();
}
} catch (IOException e) {
e.printStackTrace(); // 두 번째 자원을 닫는 과정에서 예외 발생
}
}
위 코드에서는 첫번째 자원을 닫는 과정에서 예외가 발생하면, 두번째 자원은 닫히지 않을 수 있습니다.
이는 자원 누출을 야기할 수 있습니다.
중첩된 예외 처리
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("input.txt"));
// 파일을 읽고 처리하는 코드
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace(); // 자원을 닫는 과정에서 발생한 예외 처리
}
}
}
위 코드는 자원을 닫는 과정에서 발생한 예외를 처리하기 위해 또 다른 try-catch 구문을 사용해야 합니다.
이는 코드의 가독성을 떨어뜨리고 유지보수를 어렵게 만듭니다.
위와같은 단점을 개선하기 위해 try-with-resources 구문이 나왔습니다.
try-with-resources 구문 설명
try (BufferedReader br = new BufferedReader(new FileReader("input.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("output.txt"))) {
// 파일을 읽고 쓰는 코드
} catch (IOException e) {
e.printStackTrace();
}
try-with-resources 구문을 사용하면 try 블록이 끝날 때 자원이 자동으로 해제됩니다.
자원은 AutoClosealbe 인터페이스를 구현해야 합니다.
그리고 자원이 누출될 위험이 줄어듭니다. 자원을 닫는 과정에서 예외가 발생하더라도 다른 자원들이 자동으로 닫히기 때문에 자원 누출 가능성이 없습니다.
결론
try-with-resources 구문을 사용하면, 자원 해제 과정에서 발생할 수 있는 모든 예외가 자동으로 처리되고,
코드의 가독성과 안전성이 크게 향상됩니다.
자바 프로그래밍에서 리소스를 다룰 때는 항상 try-with-resources 구문을 사용하는 것이 좋습니다.