为什么会收到NoSuchElementException?

时间:2018-11-09 18:41:10

标签: java java.util.scanner 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();
    }

1 个答案:

答案 0 :(得分:1)

扩展并弄清user3170251的注释,关闭Scanner也会关闭基础数据源,如果该数据源实际上是Closeable

  

如果此扫描仪尚未关闭,则其基础   可读性还实现了Closeable接口,然后可读性的   close方法将被调用。如果此扫描仪已经关闭,则   调用此方法无效。

Scanner.close() javadocs

作为InputStream,您的输入源System.in实际上是Closeable。一旦关闭,它就关闭了-即使将其包装在新的Scanner中,也无法再读取任何内容。这就是为什么您第二次及其后调用DataBaseModifier.options()引发的原因。

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