버퍼링 된 판독기와 파일 판독기가 닫히고 예외가 발생하면 리소스가 해제 될 것으로 예상합니다.
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의 코드 catch
는 finally
블록을 실행 하고 그 이후에 실행합니다 . 이로 인해 리소스가 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
여전히 닫힙니다. 여기 와 여기에서 자세한 내용을 확인할 수 있습니다 .