2012-09-20 67 views
60

爲什麼Eclipse在下面的代碼中給我「永遠不會關閉」的變暖「資源泄漏:」?資源泄漏:'in'永遠不會關閉

public void readShapeData() { 
     Scanner in = new Scanner(System.in); 
     System.out.println("Enter the width of the Rectangle: "); 
     width = in.nextDouble(); 
     System.out.println("Enter the height of the Rectangle: "); 
     height = in.nextDouble(); 

回答

43

因爲你不閉上你的掃描儀

in.close(); 
+28

這將關閉'Scanner'和沉默警告,但它也將關閉'System.in'其通常不期望的。 –

+0

@StuartCook +1。有些東西要留意。 – informatik01

+3

爲什麼我們需要關閉掃描儀? 「資源泄漏」是什麼意思? –

3

當你用它做你應該close您的掃描儀:一般

in.close(); 
2

,與處理的類的實例I/O應在完成後關閉。因此,在代碼結束時,您可以添加in.close()

6

它告訴你,你需要關閉在System.in上用Scanner.close()實例化的掃描儀。通常每個讀者都應該關閉。

請注意,如果您關閉System.in,您將無法再讀取它。你也可以看看Console課程。

public void readShapeData() { 
    Console console = System.console(); 
    double width = Double.parseDouble(console.readLine("Enter the width of the Rectangle: ")); 
    double height = Double.parseDouble(console.readLine("Enter the height of the Rectangle: ")); 
    ... 
} 
+2

請注意'System.console ()'在通過Eclipse運行應用程序時不可用,這在開發過程中可能很麻煩。 –

0

掃描儀應該關閉。關閉Readers,Streams ...以及這類對象來釋放資源和避免內存泄漏是一個好習慣;並在finally塊中這樣做,以確保即使在處理這些對象時發生異常也會關閉它們。

+0

這個答案實際上有助於OP知道他爲什麼應該關閉這個東西。當然,他可以閱讀文檔並查看「'scanner.close()'」,但這個答案確實有助於他/她理解正在發生的事情。 + 1 – HyperNeutrino

36

正如其他人所說,你需要在IO類上調用'close'。我要補充一點,這是使用try的理想地點 - 終於沒有catch塊,像這樣:

public void readShapeData() throws IOException { 
    Scanner in = new Scanner(System.in); 
    try { 
     System.out.println("Enter the width of the Rectangle: "); 
     width = in.nextDouble(); 
     System.out.println("Enter the height of the Rectangle: "); 
     height = in.nextDouble(); 
    } finally { 
     in.close(); 
    } 
} 

這可以確保您的掃描儀始終是閉合的,以保證適當的資源清理。由一個私人靜態掃描儀類變量聲明中

try (Scanner in = new Scanner(System.in)) { 
    ... 
} 
+1

資源泄漏是什麼意思,它會對我產生怎樣的影響? –

+4

@Borat - 「資源泄漏」意味着某些系統資源(通常是內存)不必要地丟失或浪費。通常這會在您開始在程序正常運行期間拋出OutOfMemoryErrors時影響您。 –

+0

謝謝eric。我知道你可以通過在無限循環中向自身添加一個字符串來導致錯誤。我不確定掃描儀如何導致該錯誤。 –

0
private static Scanner in; 

我固定它:

等價地,在Java 7或更高版本,可以使用「嘗試與 - 資源」的語法。不知道爲什麼修復它,但這是日食推薦我做的。

+2

您將此警告消除,但創建了資源泄漏 – zacheusz

8

您需要撥打in.close(),在finally區塊中確保其發生。

從Eclipse的文檔,這裏是爲什麼它標誌這個特殊問題(強調礦):

類實現接口java.io.Closeable(因爲JDK 1.5) 和java.lang.AutoCloseable(因爲JDK 1.7)被認爲是 代表外部資源,當它們不再需要時,它應該使用方法 close()關閉。

Eclipse Java編譯器能夠分析使用此類 類型的代碼是否符合此策略。

...

編譯器將標誌[侵犯]與 「資源泄漏: '流' 永遠不會關閉」。

完整說明here

1

加入private static Scanner in;並沒有真正解決問題,它只清除了警告。 使掃描儀保持靜態意味着它永遠保持打開狀態(或直到班級卸載,這幾乎是「永遠」)。 編譯器不再給你提示,因爲你告訴他「永遠打開它」。但那不是你真正想要的,因爲一旦你不再需要它們,你就應該關閉資源。

HTH, Manfred。

3

如果您使用的是JDK7或8,則可以使用try-catch和resources.This將自動關閉掃描儀。

try (Scanner scanner = new Scanner(System.in);) 
    { 
    System.out.println("Enter the width of the Rectangle: "); 
    width = scanner.nextDouble(); 
    System.out.println("Enter the height of the Rectangle: "); 
    height = scanner.nextDouble(); 
    } 
catch(Exception ex) 
{ 
    //exception handling...do something (e.g., print the error message) 
    ex.printStackTrace(); 
} 
0
in.close(); 
scannerObject.close(); 

它將關閉Scanner,關上了警告。

2
Scanner sc = new Scanner(System.in); 

//do stuff with sc 

sc.close();//write at end of code. 
3
// An InputStream which is typically connected to keyboard input of console programs 

Scanner in= new Scanner(System.in); 

上述線將調用與參數System.in Scanner類的構造函數,並且將返回新構造的對象的引用。

它連接到連接到鍵盤的輸入流,所以現在在運行時您可以採取用戶輸入來執行所需的操作。

//Write piece of code 

要取出內存泄漏 -

in.close();//write at end of code.