java.util.NoSuchElementException – 读取用户input的扫描器

我是使用Java的新手,但是我有一些以前使用C#的经验。 我遇到的问题是从控制台读取用户input。

我遇到了这个部分代码的“java.util.NoSuchElementException”错误:

payment = sc.next(); // PromptCustomerPayment function 

我有两个获取用户input的函数:

  • PromptCustomerQty
  • PromptCustomerPayment

如果我不打电话PromptCustomerQty那么我不会得到这个错误,这导致我相信我在做扫描仪的错误。 以下是我的完整代码示例。 我感谢任何帮助。

 public static void main (String[] args) { // Create a customer // Future proofing the possabiltiies of multiple customers Customer customer = new Customer("Will"); // Create object for each Product // (Name,Code,Description,Price) // Initalize Qty at 0 Product Computer = new Product("Computer","PC1003","Basic Computer",399.99); Product Monitor = new Product("Monitor","MN1003","LCD Monitor",99.99); Product Printer = new Product("Printer","PR1003x","Inkjet Printer",54.23); // Define internal variables // ## DONT CHANGE ArrayList<Product> ProductList = new ArrayList<Product>(); // List to store Products String formatString = "%-15s %-10s %-20s %-10s %-10s %n"; // Default format for output // Add objects to list ProductList.add(Computer); ProductList.add(Monitor); ProductList.add(Printer); // Ask users for quantities PromptCustomerQty(customer, ProductList); // Ask user for payment method PromptCustomerPayment(customer); // Create the header PrintHeader(customer, formatString); // Create Body PrintBody(ProductList, formatString); } public static void PromptCustomerQty(Customer customer, ArrayList<Product> ProductList) { // Initiate a Scanner Scanner scan = new Scanner(System.in); // **** VARIABLES **** int qty = 0; // Greet Customer System.out.println("Hello " + customer.getName()); // Loop through each item and ask for qty desired for (Product p : ProductList) { do { // Ask user for qty System.out.println("How many would you like for product: " + p.name); System.out.print("> "); // Get input and set qty for the object qty = scan.nextInt(); } while (qty < 0); // Validation p.setQty(qty); // Set qty for object qty = 0; // Reset count } // Cleanup scan.close(); } public static void PromptCustomerPayment (Customer customer) { // Initiate Scanner Scanner sc = new Scanner(System.in); // Variables String payment = ""; // Prompt User do { System.out.println("Would you like to pay in full? [Yes/No]"); System.out.print("> "); payment = sc.next(); } while ((!payment.toLowerCase().equals("yes")) && (!payment.toLowerCase().equals("no"))); // Check/set result if (payment.toLowerCase() == "yes") { customer.setPaidInFull(true); } else { customer.setPaidInFull(false); } // Cleanup sc.close(); } 

这真让我困惑了一会儿,但是这是我最终发现的。

在第一个方法中调用sc.close()时,它不仅会closures扫描器,还会closuresSystem.ininputstream。 您可以通过在第二个方法的顶部打印其状态来validation它,如下所示:

  System.out.println(System.in.available()); 

所以,现在当你重新实例化Scanner的第二种方法时,它没有find任何打开的System.instream,因此是exception。

我怀疑是否有任何出路重新打开System.in因为:

public void close() throws IOException --> Closes this input stream and releases any system resources associated with this stream. The general contract of close is that it closes the input stream. A closed stream cannot perform input operations and **cannot be reopened.**

对于你的问题唯一的好办法是在你的主要方法中启动Scanner ,在你的两个方法中作为parameter passing,然后在主方法中再次closures,例如:

main方法相关的代码块:

 Scanner scanner = new Scanner(System.in); // Ask users for quantities PromptCustomerQty(customer, ProductList, scanner ); // Ask user for payment method PromptCustomerPayment(customer, scanner ); //close the scanner scanner.close(); 

您的方法:

  public static void PromptCustomerQty(Customer customer, ArrayList<Product> ProductList, Scanner scanner) { // no more scanner instantiation ... // no more scanner close } public static void PromptCustomerPayment (Customer customer, Scanner sc) { // no more scanner instantiation ... // no more scanner close } 

希望这给你一些关于失败和可能的解决scheme的见解。

问题是

当扫描仪closures时,如果源实现了可closures的界面,它将closures其input源。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html

因此scan.close()closuresSystem.in

要修复它,你可以做

Scanner scan static ,不要在PromptCustomerQty中closures它。 下面的代码工作。

 public static void main (String[] args) { // Create a customer // Future proofing the possabiltiies of multiple customers Customer customer = new Customer("Will"); // Create object for each Product // (Name,Code,Description,Price) // Initalize Qty at 0 Product Computer = new Product("Computer","PC1003","Basic Computer",399.99); Product Monitor = new Product("Monitor","MN1003","LCD Monitor",99.99); Product Printer = new Product("Printer","PR1003x","Inkjet Printer",54.23); // Define internal variables // ## DONT CHANGE ArrayList<Product> ProductList = new ArrayList<Product>(); // List to store Products String formatString = "%-15s %-10s %-20s %-10s %-10s %n"; // Default format for output // Add objects to list ProductList.add(Computer); ProductList.add(Monitor); ProductList.add(Printer); // Ask users for quantities PromptCustomerQty(customer, ProductList); // Ask user for payment method PromptCustomerPayment(customer); // Create the header PrintHeader(customer, formatString); // Create Body PrintBody(ProductList, formatString); } static Scanner scan; public static void PromptCustomerQty(Customer customer, ArrayList<Product> ProductList) { // Initiate a Scanner scan = new Scanner(System.in); // **** VARIABLES **** int qty = 0; // Greet Customer System.out.println("Hello " + customer.getName()); // Loop through each item and ask for qty desired for (Product p : ProductList) { do { // Ask user for qty System.out.println("How many would you like for product: " + p.name); System.out.print("> "); // Get input and set qty for the object qty = scan.nextInt(); } while (qty < 0); // Validation p.setQty(qty); // Set qty for object qty = 0; // Reset count } // Cleanup } public static void PromptCustomerPayment (Customer customer) { // Variables String payment = ""; // Prompt User do { System.out.println("Would you like to pay in full? [Yes/No]"); System.out.print("> "); payment = scan.next(); } while ((!payment.toLowerCase().equals("yes")) && (!payment.toLowerCase().equals("no"))); // Check/set result if (payment.toLowerCase() == "yes") { customer.setPaidInFull(true); } else { customer.setPaidInFull(false); } } 

在附注中,您不应该使用==来进行string比较,而是使用.equals

在这行之后:

 qty = scan.nextInt(); 

总是添加一行来清除扫描仪:

 scan.nextLine(); 

另外,使用

 sc.nextLine(); 

代替

 sc.next();