[英]Scanner object has a class attribute instead of in code initialisation
今天,我在編寫服務器/客戶端應用程序時遇到了Scanner
object 的問題。 我已經解決了這個問題,但我不明白為什么我的解決方案解決了這個問題。
起初,在我的應用程序中,我在編譯項目(JAVA 8,eclipse)時遇到了一些 memory 泄漏警告,因為我使用Scanner
詢問用戶的輸入但沒有關閉它。 當我嘗試關閉掃描儀時,我的其他 class 會拋出異常,例如java.util.NoSuchElementException
。 我了解到我遇到了類似的問題: 無法在 Java 但在類之間使用多個 Scanner 對象。 當我關閉 class 中的掃描儀時,另一個 class(線程)掃描儀無法執行。 (java.util.NoSuchElementException)
我發現解決此問題的解決方案是將掃描儀 function 作為 class function 成員:
public class ClientThread extends Thread {
private Scanner scanner;
/*some code*/
}
這樣做時,我丟失了 memory 泄漏警告。
為什么將掃描儀作為 class 成員解決了警告? 是因為 class 析構函數嗎?
通常,當您創建Scanner
時,您需要在不再需要它時將其關閉。
Scanner
class 有幾個重載的構造函數,每個構造函數都采用不同類型的參數。 有一個接受File
參數的構造函數。 有一個帶有Path
參數的構造函數。 並且有一個帶有InputStream
參數的構造函數。 為了讓您的 Java 程序通過計算機鍵盤接受來自用戶的輸入,您可以使用像這樣采用InputStream
的構造函數:
Scanner scanner = new Scanner(System.in);
這是因為 class java.lang.System in
的java.lang.System
成員具有InputStream
類型。 您應該將System.in
視為封裝計算機上的鍵盤。 如果您關閉System.in
,就像關閉鍵盤一樣,這是您不應該做的事情。
現在Eclipse IDE 不夠聰明,無法意識到您的代碼正在創建一個本質上封裝計算機鍵盤的Scanner
(因此不應關閉)。 Eclipse只知道您創建的任何Scanner
最終都應該關閉,並且由於您的代碼不會關閉您創建的Scanner
,因此 Eclipse會顯示一條警告,表明您尚未關閉您創建的Scanner
。 在顯示的警告中,您將獲得三個關於如何消除警告的建議。 前兩個是指可以添加的注解,即
@SuppressWarnings("resource")
第三個建議要求您更改Eclipse配置。 您可以通過選擇出現在Eclipse IDE 頂部的Window菜單的Preferences項來執行此操作。 在Preferenes window、select Java > Compiler > Errors/Warnings 中,將Resource leak capture 設置更改為 Ignore,如下圖所示:
但是請注意,此配置設置適用於所有資源,而不僅僅是Scanner
,因此如果您在 java 代碼中打開常規文件並且不關閉它, Eclipse不會警告您。
就個人而言,我只是忽略了警告,因為我知道我不應該關閉使用System.in
創建的Scanner
或添加注釋。
雖然 Java 通常會在您離開 scope 時自動釋放 memory,但某些類需要特殊處理。
通常這些是與文件和連接(到數據庫或只是套接字)有關的類。 后者是必需的,因為底層操作系統需要顯式釋放這些資源(通常)。
在 Java 8 中引入了Autoclosable ,它解決了一些問題,但最終你需要小心。
這是具有自動關閉功能的掃描儀示例:
File file = new File("filename here");
try (Scanner in = new Scanner(file)) {
// do something here, note you dont need close as it is autoclosable
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.