首页 > 解决方案 > 为什么我会收到 NoSuchElementException?

问题描述

当我运行我的程序时,我在我的 Eclipse 控制台中得到了这个:

Type a number then press enter.
1. Add a customer
2. Add an order
3. Remove an order
4. Ship an order
5. Print pending orders with customer information
6. Restock parts
7. Exit
1
Loading driver...
Driver loaded!
Connecting database...
Database connected!
Enter 5 letters or less to identify the customer as.
Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Scanner.java:1540)

我试过只使用一个扫描仪而不是关闭它,但这没有用。有人可以帮我弄清楚为什么我会在这条线上收到这条消息tempCustID = keyboard1.nextLine();吗?奇怪的是,在读取的上一行中没有发生错误,int seed = keyboard.nextInt();.

这是我的 Menu.java 类的代码:

import java.sql.Connection;
import java.sql.SQLException;

public class Menu {

    public static void main(String[] args) throws SQLException {
        // TODO Auto-generated method stub

        DatabaseModifier session = new DatabaseModifier();
        int seed = session.options();
        Connection mycon = session.connectDB();

        while(seed != 7) {
            if(seed == 1) {
                session.addCust(mycon);
            }else if(seed == 2) {
                //session.addOrder(mycon);
            }else if(seed == 3) {

            }else if(seed == 4) {

            }else if(seed == 5) {

            }else if(seed == 6) {

            }else {
                System.out.println("Invalid option.");
            }
            seed = session.options();
        }
        System.out.println("Good-bye.");
    }
}

这是我的 DatabaseModifier.java 类的代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class DatabaseModifier {

    public int options() {      
        System.out.println("Type a number then press enter.");
        System.out.println("1. Add a customer");
        System.out.println("2. Add an order");
        System.out.println("3. Remove an order");
        System.out.println("4. Ship an order");
        System.out.println("5. Print pending orders with customer information");
        System.out.println("6. Restock parts");
        System.out.println("7. Exit");

        Scanner keyboard = new Scanner(System.in);
        int seed = keyboard.nextInt();
        keyboard.close();

        return seed;
    }

    public Connection connectDB() {
        String url = "jdbc:mysql://localhost:3306/northwind?useSSL=false&serverTimezone=EST";
        String username = "root";
        String password = "password";

        System.out.println("Loading driver...");

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("Driver loaded!");
        }catch (ClassNotFoundException e) {
            throw new IllegalStateException("Cannot find the driver in the classpath!", e);
        }

        System.out.println("Connecting database...");

        try {
            Connection mycon = DriverManager.getConnection(url, username, password);
            System.out.println("Database connected!");
            return mycon;
        } catch (SQLException e) {
            throw new IllegalStateException("Cannot connect the database!", e);
        }
    }

    public void addCust(Connection mycon) throws SQLException {
        String tempCustID, custID, comp, contName, contTitle, addr, city, reg, postCode, country, phone, fax;

        Scanner keyboard1 = new Scanner(System.in);

        int correctInput = 0;
        do {
            PreparedStatement stat = mycon.prepareStatement("SELECT CustomerID FROM customers");
            ResultSet cust = stat.executeQuery();
            System.out.println("Enter 5 letters or less to identify the customer as.");
            tempCustID = keyboard1.nextLine();
            custID = tempCustID.toUpperCase();
            while (cust.next()) {
                String customerID = cust.getString("CustomerID");
                if (custID.equals(customerID) || "".equals(custID) || "NULL".equals(custID) || "null".equals(custID) || custID.length() > 5) {
                    System.out.println(
                            "Customer ID already exists or you entered incorrect input. Please enter a different sequence of 5 letters or less to identify the customer as.");
                }else
                    correctInput = 1;
            }
        }while(correctInput == 0);

        correctInput = 0;
        do {
            PreparedStatement stat1 = mycon.prepareStatement("SELECT CompanyName FROM customers");
            ResultSet comp1 = stat1.executeQuery();
            System.out.println("Enter 40 letters or less to identify the company name.");
            comp = keyboard1.nextLine();
            while (comp1.next()) {
                String compName = comp1.getString("CompanyName");
                if (compName.equals(comp) || "".equals(comp) || "NULL".equals(comp) || "null".equals(comp) || comp.length() > 40) {
                    System.out.println(
                            "Company name already exists or you entered incorrect input. Please enter a different sequence of 40 letters or less to identify the company as.");
                }else
                    correctInput = 1;
            }
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 30 letters or less to identify the contact's first and last name.");
            contName = keyboard1.nextLine();
            if ("".equals(contName) || "NULL".equals(contName) || "null".equals(contName) || contName.length() > 30) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);


        correctInput = 0;
        do {
            System.out.println("Enter 30 letters or less to identify the contact's job title.");
            contTitle = keyboard1.nextLine();
            if ("".equals(contTitle) || "NULL".equals(contTitle) || "null".equals(contTitle) || contTitle.length() > 30) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);


        correctInput = 0;
        do {
            System.out.println("Enter 60 letters or less to identify the company's address.");
            addr = keyboard1.nextLine();
            if ("".equals(addr) || "NULL".equals(addr) || "null".equals(addr) || addr.length() > 60) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 15 letters or less to identify the company's city.");
            city = keyboard1.nextLine();
            if ("".equals(city) || "NULL".equals(city) || "null".equals(city) || city.length() > 15) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 15 letters or less to identify the company's region.");
            reg = keyboard1.nextLine();
            if ("".equals(reg) || "NULL".equals(reg) || "null".equals(reg) || reg.length() > 15) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 10 letters or less to identify the company's postal code.");
            postCode = keyboard1.nextLine();
            if ("".equals(postCode) || "NULL".equals(postCode) || "null".equals(postCode) || postCode.length() > 10) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 15 letters or less to identify the company's country.");
            country = keyboard1.nextLine();
            if ("".equals(country) || "NULL".equals(country) || "null".equals(country) || country.length() > 15) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 24 letters or less to identify the company's phone number.");
            phone = keyboard1.nextLine();
            if ("".equals(phone) || "NULL".equals(phone) || "null".equals(phone) || phone.length() > 24) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        correctInput = 0;
        do {
            System.out.println("Enter 24 letters or less to identify the company's fax.");
            fax = keyboard1.nextLine();
            if ("".equals(fax) || "NULL".equals(fax) || "null".equals(fax) || fax.length() > 24) {
                System.out.println("Incorrect input.");
            }else
                correctInput = 1;
        }while(correctInput == 0);

        keyboard1.close();

        PreparedStatement newCust = mycon.prepareStatement(
                "INSERT INTO customers" + "(CustomerID, CompanyName, ContactName, ContactTitle, Address, "
                        + "City, Region, PostalCode, Country, Phone, Fax)" + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        newCust.setString(1, custID);
        newCust.setString(2, comp);
        newCust.setString(3, contName);
        newCust.setString(4, contTitle);
        newCust.setString(5, addr);
        newCust.setString(6, city);
        newCust.setString(7, reg);
        newCust.setString(8, postCode);
        newCust.setString(9, country);
        newCust.setString(10, phone);
        newCust.setString(11, fax);
        newCust.executeUpdate();
    }

标签: javajava.util.scannernosuchelementexception

解决方案


扩展和澄清 user3170251 的评论,Scanner如果该源实际上是,则关闭 a 也会关闭基础数据源Closeable

如果这个扫描器还没有关闭,那么如果它的底层可读也实现了 Closeable 接口,那么可读的 close 方法将被调用。如果此扫描仪已关闭,则调用此方法将无效。

Scanner.close()java文档

作为一个InputStream,您的输入源System.in确实是Closeable。一旦它关闭,它就关闭了——即使你将它包装在一个新的Scanner. 这就是您第二次和后续调用DataBaseModifier.options()throw 的原因。

解决办法是避免关闭System.in。此外,重用单个Scanner而不是创建一个新的将是最安全的,因为数据可能会在内部缓冲Scanner并在您关闭它时丢失。有几种方法可以解决这个问题,但一种非常简单的方法是让你Scanner的实例变量而不是局部变量。在实例化类时初始化它,并让它永远打开。


推荐阅读