Effective Java

Effective Java | Item 9. try-finally보다는 try-with-resources를 사용하라

이진유진 2024. 5. 28. 10:07
반응형
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 구문을 사용하는 것이 좋습니다.

 

 

 

 

 

 

반응형