如何在不关闭扫描的情况下制作ONE静态扫描器全局变量并在方法和主要方法中使用它?

我想创建一个静态扫描程序,但我想在它周围放置try catch块,以便它可以自动关闭以避免资源泄漏和/或此exception:

Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Scanner.java:1585) at softwareEngineer.UserApp1.main(UserApp1.java:82) 

基本上我只想创建一个静态扫描程序声明并在整个主程序中使用它并包含静态方法,此时我的代码将需要为每个方法创建单独的扫描程序,并且你强制“scan.close()”。 由于多个扫描程序已打开且未关闭程序,下面的代码将收到exception处理错误。

我现在更新了代码,我得到空指针exception

 import java.util.Scanner; public class UserApp1 { static User currentCustomer = null; //single object static Scanner scan; //------------------------------------------------------- // Create a list, then repeatedly print the menu and do what the // user asks until they quit //------------------------------------------------------- public static void main(String[] args) { scan = new Scanner(System.in);)//scanner to avoid resource leak printMenu(); //print menu system from another function String choice = scan.nextLine(); //reads an input final String EXIT_now = "0"; final String BACK = "back"; while (!(choice.equalsIgnoreCase(EXIT_now))){ switch(choice) { case 1: break; case 2: currentCustomer = loginInput(); "); } //ends printMenu public static User loginInput(){ System.out.print( "\nFollow the Prompts to Log-In to your Account \n "); System.out.print( "\nPlease enter your userid : \n "); String userid = scan.nextLine();// <---- errors happens here System.out.print( "\nPlease enter your password: \n "); String pass = scan.nextLine(); currentCustomer = AccountList.loginUser(userid, pass); if (currentCustomer != null) { return currentCustomer; } return null; }//ends loginInput }//ends class* 

您正在使用try-with-resources,它会在您完成try块时自动关闭它。 尝试将其设置为如下变量:

 public class MyClass { private static Scanner scan; public static void main(String[] args) { scan = new Scanner(System.in); } } 

避免使用System.in输入制作多个扫描仪,因为它们将使用流,然后您有一个完全不同的问题。

通过将要使用的Scanner实例传递给相关方法,完全避免使用静态全局扫描程序。 考虑这个简化的例子:

 public static void main(String[] args) { try(Scanner in = new Scanner(System.in)) { String choice = in.nextLine().trim(); if(choice.equals("1")) { doOp1(in); } else if(choice.equals("2")) { doOp2(in); } else { System.err.println("Invalid choice. Goodbye."); } } } // Method takes an open, functioning Scanner as an argument, therefore // it doesn't need to close it, or worry about where it came from, it // simply uses it, does what it needs to do, and returns, trusting // the caller to properly close the Scanner, since it opened it. private void doOp1(Scanner in) { System.out.print("What is your name? "); String name = in.nextLine().trim(); System.out.print("What is your favorite color? "); String color = in.nextLine().trim(); } private void doOpt2(Scanner in) { ... } 

您希望划分资源,以确保它们的范围有限且易于关闭。 将它们置于任何类型的全局状态使得这非常困难。 相反,使用它将资源的打开和关闭与代码分开。 这种划分使得代码更易于维护,可读和可测试。

例如,通过将已经打开的Scanner传递给您的核心业务逻辑函数,您可以通过构建从硬编码字符串读取的Scanner并将其传递到其中来模拟真实用户的行为并创建测试以确保代码保持稳定。您的方法,无需运行整个类并一次又一次地手动输入您的测试行为。