자바에서 finally 블록은 항상 실행되는가요?
네, Java에서 finally 블록은 예외 발생 여부와 관계없이 항상 실행됩니다. try 블록 또는 catch 블록에서 return 문 또는 예외 throw가 발생하더라도 finally 블록은 반드시 실행됩니다.
설명:
- try-catch-finally 블록:
- try 블록: 예외가 발생할 가능성이 있는 코드를 포함합니다.
- catch 블록: try 블록에서 발생하는 예외를 처리합니다.
- finally 블록: 예외 발생 여부와 관계없이 항상 실행되는 코드를 포함합니다. 일반적으로 리소스 해제 또는 정리 작업을 수행하는 데 사용됩니다.
finally 블록이 항상 실행되는 이유:
- 핵심 목적: 리소스 누수 방지 및 시스템 상태 유지 보장
- 예외 발생 시에도 리소스가 제대로 해제되지 않으면 시스템 오류로 이어질 수 있습니다.
- finally 블록을 사용하면 예외 상황에서도 리소스 해제를 명시적으로 수행하여 시스템 안정성을 유지할 수 있습니다.
finally 블록 실행 시점:
- try 블록이 정상적으로 종료되는 경우:
- try 블록의 모든 코드가 실행된 후 finally 블록이 실행됩니다.
- 예외가 발생하는 경우:
- catch 블록이 실행된 후 finally 블록이 실행됩니다.
- 여러 catch 블록이 존재하는 경우, 해당 예외를 처리하는 catch 블록 실행 후 finally 블록이 실행됩니다.
- try 블록에서 return 문이 실행되는 경우:
- try 블록에서 예외를 throw하는 경우:
- 예외가 throw된 후 finally 블록이 실행됩니다.
주의 사항:
- finally 블록에서 예외를 throw하는 경우:
- finally 블록에서 발생하는 예외는 이전 예외를 마스킹합니다. 즉, 이전 예외가 더 이상 처리되지 않습니다.
- 따라서 finally 블록에서 throw하는 예외는 신중하게 사용해야 합니다.
예시:
public class FinallyExample {
public static void main(String[] args) {
try {
// 예외 발생 가능성이 있는 코드
int result = 10 / 0; // ArithmeticException 발생
} catch (ArithmeticException e) {
System.out.println("예외 처리: " + e.getMessage());
} finally {
System.out.println("finally 블록 실행");
}
}
}
예제 코드: finally 블록과 리소스 해제
public class FinallyExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("파일 닫기");
}
}
}
try-with-resources
문을 사용하여BufferedReader
객체를 생성합니다. 이 문은 자동으로 리소스 해제를 수행합니다.BufferedReader
객체는finally
블록 밖에서도 닫히지만, 명시적으로 닫는 것이 더 안전합니다.finally
블록에서reader.close()
를 호출하여 파일을 닫습니다. 예외가 발생하더라도close()
메서드가 실행됩니다.
추가 예시:
다음 예제 코드에서는 데이터베이스 연결을 열고 사용한 후, finally 블록을 사용하여 연결을 닫습니다.
public class FinallyExample {
public static void main(String[] args) {
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "user", "password");
// 데이터베이스 작업 수행
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
Java에서 finally 블록 대신 리소스 해제를 위한 대체 방법
try-with-resources 문:
- Java 7에서 도입된 새로운 문법입니다.
- 리소스 객체를 자동으로 열고 닫아 finally 블록 없이도 리소스 해제를 수행할 수 있습니다.
- 가장 간결하고 안전한 방법이며, 권장되는 방식입니다.
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
AutoCloseable 인터페이스:
- try-with-resources 문에서 사용되는 리소스 객체가 구현해야 하는 인터페이스입니다.
close()
메서드를 통해 리소스를 해제합니다.
public class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
// 리소스 해제 코드
}
}
public class FinallyExample {
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
// 리소스 사용 코드
}
}
}
직접 해제 코드 작성:
- finally 블록을 사용하여 직접 리소스 해제 코드를 작성합니다.
- try-with-resources 문이나 AutoCloseable 인터페이스를 사용하지 않는 경우에 사용됩니다.
- 코드가 다소 번거롭고, 실수로 리소스를 해제하지 않는 경우가 발생할 수 있습니다.
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("test.txt"));
// 리소스 사용 코드
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 위의 대체 방법들을 사용할 때는, 예외 상황에서도 리소스가 제대로 해제되는지 반드시 확인해야 합니다.
- 특히, 직접 해제 코드를 작성하는 경우에는 주의가 필요합니다.
java error-handling return