Java9 Try-With-Resources


在這篇文章中,我們將討論Java SE 9中的一些改進Try-With-Resources語句。現在讓我們開始學習這個構造。

Java SE 7:Try-With-Resources基礎知識

Java SE 7引入了一個新的構造:Try-With-Resources 語句,用於更好的例外處理。 如果沒有這個構造,開發人員必須編寫大量冗餘和難看的程式碼。 如果開發人員忘記正確關閉資源,那麼可能在應用程式中有資源洩漏問題。

這個新功能的主要目標是:

  • 語法更精簡,避免寫一些try-catch/finally塊。
  • 程式碼且有更好的可讀性
  • 不需要做空檢查
  • 無需檢查資源參照是指參照物件還是null
  • 更好的資源管理,ARM(自動資源管理)
  • 避免記憶體洩漏

Try-With-Resources 範例-1

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("mytest.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}

這裡建立了一個實用程式方法,它建立一個BufferedReader物件來讀取檔案的內容。 如果觀察上面的程式碼片段,即使reader1參照了BufferedReader物件,也應該建立一個重複的reader2來在Try-With-Resources中使用它。 這是Java SE 7或8版本中的一個小錯誤或問題。

我們不能在Try-With-Resources語句的try()塊內使用任何資源(在Try-With-Resources之外宣告)。

以下程式碼在Java SE 7或8版本中無效,它會引發編譯時錯誤。

Try-With-Resources 範例-2

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("mytest.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}

Java SE 7:Try-With-Resources規則

在Java SE 7或8版本中,我們應該遵循這些規則為自動資源管理(ARM)來使用Try-With-Resources語句,

  • 任何資源(其中預定義的Java API類或使用者定義的類)必須實java.lang.AutoCloseable
  • 資源物件必須參照final或有效的final變數
  • 如果資源已經在Try-With-Resources語句之外宣告,則應該重新參照區域性變數(如上面的範例-1中的程式碼所示)
  • 新建立的區域性變數可以在Try-With-Resources語句中使用。

Java SE 9:Try-With-Resources改進

Java SE 9為Try-With-Resources語句提供了一些改進。 正如我們在前面幾節中討論的那樣,Java SE 7或8版本在這個語句中有一個小問題或錯誤。

在Java SE 9中,如果我們有一個已經在Try-With-Resource語句之外宣告的資源作為final或有效的final,那麼不需要宣告區域性變數。 我們可以在Try-With-Resource語句中使用以前建立的變數,沒有任何問題,如下所示:

Try-With-Resources 範例-3

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("mytest.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}

這個例子是Java SE 9的有效程式碼。我們不會像範例1 所示的那樣建立另一個區域性變數,如reader2來參照reader1。下面在Java SE 9 REPL中執行這兩個範例來測試它們。如下所示 -

jshell> void testARM_Before_Java9() throws IOException{
   ...> BufferedReader reader1 = new BufferedReader(new FileReader("mytest.txt"));
   ...> try (BufferedReader reader2 = reader1) {
   ...> System.out.println(reader2.readLine());
   ...> }
   ...> }
|  created method testARM_Before_Java9()

jshell> testARM_Before_Java9()
mytest

測試範例-3使用Java SE 9 REPL

jshell> void testARM_Java9() throws IOException{
   ...> BufferedReader reader1 = new BufferedReader(new FileReader("mytest.txt"));
   ...> try (reader1) {
   ...> System.out.println(reader1.readLine());
   ...> }
   ...> }
|  created method testARM_Java9()

jshell> testARM_Java9()
mytest

上面就是「Java SE 9:Try-With-Resources改進」新功能的全部內容。