[Effective Java] 아이템 9 : try-finally 보다는 try-with-resources를 사용하라

2022. 3. 31. 18:15Java/Effective Java

728x90
반응형


try-finally

InputStream, OutputStream, java.sql.Connection  -> 클라이언트가 지나칠 가능성이 있기에 성능에도 문제를 줄 수 있다.
그래서 안전망으로 아이템 8에서 사용한 Finalizer를 사용한다. 또한, 자원이 닫히는 것을 보장하는 try-finally가 존재한다.

https://devaily.tistory.com/34

 

[Effective Java] 아이템 8 : finalizer와 cleaner 사용을 피하라

자바의 객체 소멸자 Finalizer : 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요, 그냥 쓰지 마세요.. 그냥 쓰지 말라고 Cleaner : Finalizer 보다는 덜 위험하지만, 여저힌 위험하고, 불

devaily.tistory.com


try-with-resources

// try-finally를 사용한 코드

static String firstLineOfFile(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        br.close();
    }
}

// try-with-resources를 사용한 코드

static String firstLineOfFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(parth))) {
    return br.readLine();
    }
}

먼저 작성한 try-finally 코드는 try 블록과 finally 블록에서 예외가 모두 발생할 수 있다. 만약 물리적인 이유로 readLine 메소드에서 예외가 발생하여 close()를 실패하게 될 것이다.

 

만약 이러한 상황이 발생한다면 두 번째 예외에서 첫 번째 예외를 무시하게 될 것이고, StackTrace에는 두 번째 예외에 대한 오류만 나오기에 내가 어디서 오류가 났는지 정확히 알기 어렵다.

 

이를, 방지하기 위해 자바 7에서 지원하는 try-with-resources가 탄생하였다.

try-with-resources를 사용하기 위해서는 처리할 자원이 AutoCloseable 인터페이스를 구현해야 한다.

try-with-resources를 사용하기 위해 많은 자바 라이브러리와 서드 파티 요소들이 AutoCloseable을 구현하고 있다.

다음은 자원이 둘 이상 사용되는 코드이다.

// try-finally 사용 코드

static void copy(String src, String dst) throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        Outputstream out = new FileOutputStream(dst);
        try {
            byte [] buf = new byte[BUFFER_SIZE];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        } finally {
            out.close();
        }
    }
}

// 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);
    }
}

try-with-resources 코드가 더 짧고 읽기 편하다. 이 처럼 나타낼 예외 하나만 존재하고 나머지는 숨김으로써 StackTrace에도 버려지는 것이 아닌 숨겨짐으로 인식되게 된다.

 

또한, try-with-resources는 try문과 동일하게 catch 문을 사용할 수 있어 try 중첩을 사용하지 않아도 다수의 예외를 처리할 수 있다.

728x90
반응형