2015-02-08 55 views
2

在以下代碼中,我已經在try-catch塊之外聲明瞭引用類型變量。然後我在try塊中初始化它,並嘗試在最終塊中再次使用它。但編譯器警告我有關變量在最終塊內未初始化的情況。在本地塊內初始化的引用類型在本地塊外部未初始化

從我的理解,因爲我已經初始化了try塊中的file變量,所以在最後的塊中它不應該爲空。

import java.io.*; 

class test { 
    public static void main (String ... args) throws IOException{  
     FileInputStream file; 
     // Solution : FileInputStream file = null; 

     try { 
      file = new FileInputStream("data");   
     } 
     catch(IOException exc) { 
      System.out.println("Error Occured!"); 
     } 
     finally { 
      file.close(); // Error : variable file might not have been initialized 
     } 
    } 
} 

我通過初始化文件變量爲null解決了這個問題。

我的問題是,爲什麼初始化try塊內的引用變量後,變量將保持未初始化在最後的塊?


我初始化if語句中file變量時遇到了同樣的問題,

import java.io.*; 

class test{ 
    public static void main (String ... args) throws IOException{  
    FileInputStream file; 
    // Solution : FileInputStream file = null; 

    int i = 0; 
    if(i > 5){ 
     file = new FileInputStream("data"); 
    } 

    file.close(); // Error : variable file might not have been initialized 
    } 
} 
+1

只需在'try'(或聲明它的位置)之前將其設置爲'null'即可。編譯器要求變量被認爲是沿所有路徑初始化的,並且如果'try'在賦值語句之前有異常,它將不會被初始化。 – 2015-02-08 05:05:58

+1

(如果變量只在'if'語句中設置,即使後面只在另一個具有相同條件的if語句中引用它,也會遇到同樣的問題。) – 2015-02-08 05:07:59

+0

@HotLicks謝謝。所以,java只會首先在最外面的範圍內進行查找,並發現未經初始化而使用變量的問題。所以我基本上可以將我的程序分成兩個範圍,無條件的和有條件的? – 2015-02-08 21:43:35

回答

1

的誤差可能未初始化,它可能是,如果構造函數拋出Exception(其它可能)。另外,您也可以使用try-with-resources close這將close()

try (InputStream file = new FileInputStream("data")) { 
    // ...    
} 
catch(IOException exc){ 
    // What error. 
    System.out.println("Error Occurred! " + exc.toString()); 
    exc.printStackTrace(); 
} 

或者,

finally { 
    if (file != null) { 
    try { 
     file.close(); 
    } catch (Exception ignored) { 
    } 
    } 
} 
+0

我的問題是,爲什麼初始化在try塊之外失蹤。對困惑感到抱歉。爲了清晰起見,我更新了我的問題。 – 2015-02-08 05:05:00

+1

@iamcreasy我明白了,我的答案是解釋爲什麼。 – 2015-02-08 05:05:48

3

的問題是,如果new FileInputStream("data")拋出,那麼file變量不會從最終塊內。你可以通過捕捉資源來解決這個問題。

try (FileInputStream file = new FileInputStream("data")){ 
} 
catch(IOException exc){ 
    System.out.println("Error Occured!"); 
} 

如果你有資源嘗試,那麼你將不再需要的最後一塊關閉流.... java會爲你關閉它。

您還可以在最後一個塊中關閉它之前檢查它是否爲空。