使用 Java 關閉掃描儀
1. 簡介
當我們使用 Java 的Scanner
類別從System.in
讀取輸入時,某些 IDE 可能會警告潛在的資源洩漏。例如,如果我們沒有明確關閉Scanner
,**我們可能會遇到類似「 Resource leak: 'scanner' is never closed
」的警告**。但是,關閉連接到System.in
Scanner
需要小心處理,以避免意外問題。
在本教程中,我們將了解關閉Scanner
為何重要以及如何在 Java 中執行此操作。
2. 理解警告
在Java中,我們應該在使用後關閉文件,網路連接和輸入流等資源,以釋放系統記憶體。 Scanner
類別從各種來源(包括檔案和System.in
)讀取輸入,例如原始值和字串。由於它實現了Closeable
接口,因此它保存了不再需要時應釋放的資源。
如果我們沒有正確關閉Scanner
對象,某些 IDE(例如 Eclipse 和 Visual Studio Code)會顯示警告。例如,如果我們沒有明確關閉Scanner
對象,IDE 將顯示資源洩漏警告:
3. 使用close()
方法關閉Scanner
在 Java 中,我們可以使用close()
方法關閉Scanner
,這有助於釋放系統資源。從檔案或System.in
讀取時這一點尤其重要。
建議在finally
區塊中關閉Scanner
,以確保即使發生異常也能正確關閉。這有助於防止資源洩漏:
@Test
void givenUserName_whenGetGreetingMessage_thenReturnsWelcomeMessage() {
String input = "Anees\n";
ByteArrayInputStream inputStream = new ByteArrayInputStream(input.getBytes());
Scanner scanner = new Scanner(inputStream);
ScannerClose example = new ScannerClose();
String result = example.getGreetingMessage(scanner);
assertEquals("Hi, Anees Welcome to Baeldung", result);
scanner.close();
}
關閉資源是一種很好的做法。但是,關閉連結到System.in
Scanner
可能會導致問題。 System.in
流代表標準輸入流,通常是鍵盤。如果我們關閉該流,程式就無法再讀取使用者輸入,而且我們無法在同一程式執行中重新開啟System.in
。
此外,如果我們為System.in
建立多個Scanner
實例,關閉其中任何一個都會關閉整個程式的輸入流。因此,當我們再次嘗試讀取輸入時,我們可能會遇到異常:
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hi, " + name + " Welcome to Baeldung!");
scanner.close();
System.out.print("Enter your age: ");
int age = scanner.nextInt();
System.out.println("Your age is: " + age);
在這裡,我們嘗試讀取age
,但是Scanner
早已關閉。結果,我們遇到異常IllegalStateException: Scanner closed
:
Enter your name: Anees
Hi, Anees Welcome to Baeldung!
Enter your age: Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.base/java.util.Scanner.ensureOpen(Scanner.java:1150)
at java.base/java.util.Scanner.next(Scanner.java:1573)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
為了避免Scanner
出現問題,我們應該對System.in
使用單一實例,並且避免關閉它或僅在不再需要輸入時關閉它。
4. 使用try-with-resources
關閉Scanner
我們可以使用try-with-resources
在區塊結束時自動關閉Scanner
,即使發生異常。這種方法消除了對finally
區塊的需要並自動關閉資源,從而降低了資源洩漏的風險:
@Test
void givenUserName_whenGetGreetingMessage_thenReturnsWelcomeMessage() {
String input = "Anees\n";
ByteArrayInputStream inputStream = new ByteArrayInputStream(input.getBytes());
String result;
try (Scanner scanner = new Scanner(inputStream)) {
ScannerTryWithResources example = new ScannerTryWithResources();
result = example.getGreetingMessage(scanner);
}
assertEquals("Hi, Anees Welcome to Baeldung", result);
}
當try
區塊執行完畢後,Java會自動關閉Scanner
實例,讓程式碼更簡潔可靠。因此,建議try-with-resources
,因為它可以確保在關閉Scanner
時進行正確的清潔。
5. 結論
在本文中,我們了解了關閉Scanner
為何重要以及如何正確關閉掃描器。適當的資源管理有助於防止洩漏並確保程序順利執行。
雖然讀取文件時需要關閉Scanner
,但處理System.in
時需要格外小心。使用單一Scanner
實例並僅在不再需要輸入時關閉它有助於避免問題。
try-with-resources
方法透過確保自動關閉簡化了資源管理,使程式碼更清晰、更可靠。
與往常一樣,完整的範例程式碼可在 GitHub 上取得。