Saya mengharapkan pembaca buffer dan pembaca file untuk menutup dan sumber daya dilepaskan jika pengecualiannya dibuang.
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
return read(br);
}
}
Namun, apakah ada persyaratan untuk memiliki catch
klausul agar penutupan berhasil?
EDIT:
Pada dasarnya, apakah kode di atas di Java 7 sama dengan kode di bawah untuk 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;
}
java-7
try-with-resources
Cheetah
sumber
sumber
catch
dari contoh Anda untuk Java 6. Yaitucatch (Exception ex) { throw ex; }
- ini hanya membuang kembali pengecualian, tidak melakukan apa-apa, dapat dengan mudah dihapus tanpa ada cedera. Atau apakah saya melewatkan sesuatu?Jawaban:
Itu benar dan tidak ada persyaratan untuk
catch
klausul. Oracle java 7 doc mengatakan bahwa sumber daya akan ditutup terlepas dari apakah pengecualian benar-benar dilemparkan atau tidak.Anda harus menggunakan
catch
klausa hanya jika Anda ingin bereaksi atas pengecualian tersebut. Thecatch
klausul akan dilaksanakan setelah sumber daya ditutup.Berikut cuplikan dari tutorial Oracle :
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.
EDIT
Mengenai pertanyaan baru yang diedit:
Kode di Java 6 mengeksekusi
catch
dan setelah itufinally
blok. Ini menyebabkan sumber daya masih berpotensi dibuka dicatch
blokir.Di Jawa 7 sintaks, sumber ditutup sebelum yang
catch
blok, sehingga sumber daya yang sudah ditutup selamacatch
eksekusi blok. Ini didokumentasikan di tautan di atas:sumber
Penggunaan try-with-resources Anda akan berfungsi dengan baik dalam kasus khusus ini, tetapi secara umum tidak sepenuhnya benar. Anda tidak boleh merantai sumber daya seperti itu karena dapat menimbulkan kejutan yang tidak menyenangkan. Asumsikan Anda memiliki ukuran buffer variabel:
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); } }
Asumsikan ada yang tidak beres dan Anda berakhir dengan
sz
sikap negatif. Dalam hal ini sumber file Anda (dibuat melaluinew FileReader(filePath)
) TIDAK akan ditutup.Untuk menghindari masalah ini, Anda harus menentukan setiap sumber daya secara terpisah seperti ini:
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); } }
Dalam kasus ini bahkan jika inisialisasi
br
gagalfile
masih ditutup. Anda dapat menemukan detail lebih lanjut di sini dan di sini .sumber
new FileReader(filePath))
tidak akan ditutup jika anIllegalArgumentException
dilempar ketika sz negatif. Bukankah try-with-resources menutup semuaAutoClosable
resource terlepas dari pengecualian apa pun yang dilempar?.close()
variabel yang telah dideklarasikan di penginisialisasi try-with-resources. Itulah mengapa memisahkannya menjadi dua deklarasi dalam contoh ini berhasil.sz < 0
menyebabkan konstruktor mengeluarkan pengecualian sebenarnya akan menyebabkan sumber daya bocor.