SSAFY11th-book-study / book-study

SSAFY 11기 6반의 '토비의 스프링 스터디'
0 stars 0 forks source link

3.1 try-with-resource #24

Closed limjongheok closed 6 months ago

limjongheok commented 6 months ago
public void deleteAll() throws SQLException, ClassNotFoundException {

        Connection c = null;
        PreparedStatement ps = null;

        try{
            c = connectionMaker.makeConnection();
            StatementStrategy statementStrategy = new DeleteAllStatement();
            ps = statementStrategy.makePreparedStatement(c);
            ps.executeUpdate();
        }catch (SQLException e){
            throw e;
        }finally {
            if(ps !=null){
                try {
                    ps.close();
                }catch (SQLException e){

                }
            }
            if(c!=null){
                try {
                    c.close();
                }catch (SQLException e){

                }
            }
        }
    }

다음 같은 코드를

public void deleteAll2() throws SQLException, ClassNotFoundException {

        StatementStrategy statementStrategy = new DeleteAllStatement();

        try( Connection c = connectionMaker.makeConnection(); 
            PreparedStatement ps = statementStrategy.makePreparedStatement(c);
        ) {
            ps.executeUpdate();
        }
        catch (SQLException e){
            throw e;
        }
    }

다음과 같이 try-with-resource 를 활용하면 finally 에서 close 할 필요 없이 autoClose 할 수 있는 것으로 알고 있습니다. 이는 image 다음과 같이 AutoCloseable 인터페이스를 확장하였기 때문인데

public interface AutoCloseable {
    void close() throws Exception;
}

이 AutoCloseable은 단순 close 메소드만 있고 이를

public interface Connection  extends Wrapper, AutoCloseable {
 void close() throws SQLException;
}

다음과 같이 구현을 하는데

try-with-resource는 어떤 원떤 원리로 close를 해 주는 지 모르겠습니다.
또한 try-with-resource 가 try-catch-finally 단점을 보안 해 주기 위해 생성 되었고 장점도 더 많던데 그렇다면 자바 7 이후 부터로는 try-catch-finally 보다 무조건 적인 try-with-resource 사용이 옳은 건가요??

sootudio commented 6 months ago

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

try-with-resource에 대한 자바의 공식 문서에 다음과 같은 내용이 있었습니다.

- The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:

public static void writeToFileZipFileContents(String zipFileName,
                                           String outputFileName)
                                           throws java.io.IOException {

    java.nio.charset.Charset charset =
         java.nio.charset.StandardCharsets.US_ASCII;
    java.nio.file.Path outputFilePath =
         java.nio.file.Paths.get(outputFileName);

    // Open zip file and create output file with 
    // try-with-resources statement

    try (
        java.util.zip.ZipFile zf =
             new java.util.zip.ZipFile(zipFileName);
        java.io.BufferedWriter writer = 
            java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {
        // Enumerate each entry
        for (java.util.Enumeration entries =
                                zf.entries(); entries.hasMoreElements();) {
            // Get the entry name and write it to the output file
            String newLine = System.getProperty("line.separator");
            String zipEntryName =
                 ((java.util.zip.ZipEntry)entries.nextElement()).getName() +
                 newLine;
            writer.write(zipEntryName, 0, zipEntryName.length());
        }
    }
}

- In this example, the try-with-resources statement contains two declarations that are separated by a semicolon: ZipFile and BufferedWriter.

- When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the BufferedWriter and ZipFile objects are automatically called in this order.

- Note that the close methods of resources are called in the opposite order of their creation.

제가 이해한 대로라면, try 블록의 아래 블록이 (정상적 또는 예외적으로) 종료되면, try-with-resource 구문이 AutoCloseable의 close 메소드를 호출한다고 이해했습니다.

또한, 다음 내용에 try-catch와 try-with-resource의 사용에 대해서 나와 있었는데... - Therefore, use a try-with-resources statement instead of a finally block to close your program's resources.

위 내용대로라면 자원 누출의 방지와 자원 종료 순서 보장을 위해 try-with-resource가 더 유리한 것으로 이해하긴 했습니다.

예외적인 상황도 있을 것 같은데... 당장 생각하기에는 여러 예외 상황에 따라 다른 처리를 하거나, 특정 예외 상황을 무시하고자 할때는 try-catch가 더 유리할 것 같다는 생각이 듭니다.

limjongheok commented 6 months ago
  1. 컴파일러가 해결 try catch finally 안에 있음
  2. 정상적으로 종료시 try with resource 구문이 autocloseAble 의 close 메소드 호출
  3. 특정상황시 try catch finally 필요 (닫는 자원이 없는 상황)