[java-7] Java 7 try-with-resources를 올바르게 사용하고 있습니까?

버퍼링 된 판독기와 파일 판독기가 닫히고 예외가 발생하면 리소스가 해제 될 것으로 예상합니다.

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
    {
        return read(br);
    }
}

그러나 catch성공적인 폐쇄를위한 조항 이 있어야 합니까?

편집하다:

본질적으로 Java 7의 위 코드는 Java 6에 대해 아래에 해당합니다.

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{

    BufferedReader br = null;

    try
    {
        br = new BufferedReader(new FileReader(filePath));

        return read(br);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        try
        {
            if (br != null) br.close();
        }
        catch(Exception ex)
        {
        }
    }

    return null;
}



답변

정확하고 catch절에 대한 요구 사항이 없습니다 . Oracle Java 7 문서는 예외가 실제로 발생했는지 여부에 관계없이 리소스가 닫힐 것이라고 말합니다 .

catch예외에 대응하려는 경우에만 절을 사용해야합니다 . catch조항이 실행됩니다 리소스가 닫힙니다.

다음은 Oracle 자습서의 일부입니다 .

다음 예제는 파일에서 첫 번째 줄을 읽습니다. BufferedReader 인스턴스를 사용하여 파일에서 데이터를 읽습니다. BufferedReader는 프로그램이 완료된 후 닫아야하는 리소스입니다.

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
} // In this example, the resource declared in the try-with-resources statement is a BufferedReader.

… BufferedReader 인스턴스는 try-with-resource 문에서 선언되기 때문에 try 문이 정상적으로 완료되는지 갑작스럽게 완료되는지에 관계없이 닫힙니다 (IOException을 던지는 BufferedReader.readLine 메서드의 결과로).

편집하다

새로 수정 된 질문에 관하여 :

Java 6의 코드 catchfinally블록을 실행 하고 그 이후에 실행합니다 . 이로 인해 리소스가 catch블록 에서 여전히 잠재적으로 열립니다 .

자바 7 구문에서 자원 폐쇄 전에catch 블록 때문에 자원이 이미 동안 닫혀 catch블록 실행. 이것은 위 링크에 설명되어 있습니다.

try-with-resources 문에서 catch 또는 finally 블록은 선언 된 리소스가 닫힌 후에 실행됩니다.


답변

try-with-resources의 사용은이 특정 경우에 잘 작동하지만 일반적으로 정확하지 않습니다. 불쾌한 놀라움으로 이어질 수 있으므로 이와 같은 리소스를 연결해서는 안됩니다. 가변 버퍼 크기가 있다고 가정합니다.

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz))
    {
        return read(br);
    }
}

무언가 잘못되어 결국 sz부정적 이라고 가정하십시오 . 이 경우 파일 리소스 (를 통해 생성됨 new FileReader(filePath))가 닫히지 않습니다 .

이 문제를 방지하려면 다음과 같이 각 리소스를 개별적으로 지정해야합니다.

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (FileReader file = new FileReader(filePath);
         BufferedReader br = new BufferedReader(file, sz))
    {
        return read(br);
    }
}

이 경우 초기화가 br실패 하더라도 file여전히 닫힙니다. 여기여기에서 자세한 내용을 확인할 수 있습니다 .


답변