본문 바로가기

Language/Java

finally

 

우리의 프로그램은 프로그램 외부의 자원(Resource)에 접근해서 작업을 진행할 수 있다. 대표적인 자원으로는 파일, 네트워크, 데이터베이스 등이 있다. 이러한 자원들은 프로그램 외부에 존재하기 때문에 우리의 프로그램이 온전히 제어하지 못한다. 우리의 프로그램만을 위해 존재하지 않기 때문에 읽기나 쓰기 작업을 하는 도중에 상황에 따라 연결이 불량하여 작업이 실패할 수 있다. 그래서 이러한 자원을 사용할 때는 자원을 붙들기 위해 파일의 경우 점유상태를 나타내기도 하고, 네트워크나 데이터베이스는 연결 상태를 유지한다. 그리고 우리가 필요한 작업을 끝내고 나서는 자원을 놓아주는 작업을 한다.

 

작업이 끝나고 붙잡고 있던 것을 놔줘야 한다. 이때 공통적으로 사용되는 메소드가 close 이다.

 

try 문에서 오류가 발생하면 이후에 작업이 있더라도 catch 문으로 넘어간다. 그래서 자원을 놓아주는 작업을 try 문에 넣게 되면, 예외가 발생했을 때 자원을 놓아주는 작업을 하지 못하게 된다. 그래서 예외가 발생했든, 발생하지 않았든 일단 잡았으면 놓아주는 작업을 실행하도록 해야 한다.

 

이런 경우에 사용하는 형식이 finally 문이다. finally 문은 try 문에서 예외가 발생했거나 발생하지 않았거나 무조건 실행된다.

 

import java.io.FileWriter;
import java.io.IOException;

public class CheckedExceptionApp {

	public static void main(String[] args) {
		FileWriter f = null;
		try {
			f = new FileWriter("data.txt");
			f.write("Hello");
			// close를 하기 전에 예외가 발생한다면 close가 실행되지 않음
			// f.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (f != null) {
				try {
					f.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}			
		}
	}

}

 

위 코드를 보면, try 안에서 Exception이 발생했든 안 했든 무조건 finally가 실행이 된다. 그래서 close는 finally에 넣어야 한다.

 

그런데, 만약 변수 f가 try 문 안에서 선언이 되면, try 문 안에 있으면 finally 문 안에서 f.close() 가 작동할 수 없게 된다. 그래서 try 문 바깥에서 우선 변수 f를 선언해줘야 한다.

 

또, finally 문 안에 그냥 f.close(); 라고 입력해두면 오류가 발생한다. f라고 하는 것이 초기화가 되지 않았기 때문이다. 만약 try 문에서 Exception이 발생해서 이 코드 자체가 실행이 안 됐다면, 무조건 finally로 가게 되는데 그때에는 f가 없다. 그러면 존재하지 않는 것을 close 하는 것이기 때문에 문제가 된다. 그래서 f가 세팅이 되어 있을 때에만 close가 되도록 조건문을 사용해주면 된다. f가 null이 아닐 경우에만 close()를 실행하도록 하는 것이다.

 

그런데 조건문 안에 f.close()를 넣어놨을 때에도 IOException이 발생할 수 있다고 오류 메세지가 뜬다. close도 IO 작업이기 때문이다. 그래서 finally 문 안에서도 try catch를 하여 IOException 처리를 해야 한다.

 

 

 

 

 

[참고자료]

https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

 

The finally Block (The Java™ Tutorials > Essential Java Classes > Exceptions)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated

docs.oracle.com

'Language > Java' 카테고리의 다른 글

throw, throws  (0) 2022.11.26
try with resource  (0) 2022.11.26
Checked Exception vs Unchecked Exception  (0) 2022.11.26
catch문의 e  (1) 2022.11.26
예외의 우선순위  (0) 2022.11.26