简体   繁体   English

为什么会收到NoSuchElementException?

[英]Why am I receiveing a NoSuchElementException?

I'm getting this in my Eclipse console when I run my program: 运行程序时,这是在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)

I've tried using just one Scanner and not closing it, but that didn't work. 我尝试仅使用一个扫描仪而不关闭它,但这没有用。 Can someone please help me figure out why I'm getting this message on the line that reads, tempCustID = keyboard1.nextLine(); 有人可以帮我弄清楚为什么我在显示以下内容的行上收到此消息: tempCustID = keyboard1.nextLine(); ? What's weird is that no error occurs during the previous line that reads, int seed = keyboard.nextInt(); 奇怪的是,在读取的上一行没有错误发生, int seed = keyboard.nextInt(); .

Here's the code for my Menu.java class: 这是我的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.");
    }
}

And here's the code for my DatabaseModifier.java class: 这是我的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();
    }

Expanding upon and clarifying user3170251's comment, closing a Scanner also closes the underlying data source if that source is in fact Closeable : 扩展并阐明user3170251的注释,如果实际上是Closeable ,则关闭Scanner还会关闭基础数据源:

If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked. 如果尚未关闭此扫描器,则如果其基础可读文件也实现了Closeable接口,则将调用该可读文件的close方法。 If this scanner is already closed then invoking this method will have no effect. 如果此扫描仪已经关闭,则调用此方法将无效。

( Scanner.close() javadocs ) Scanner.close() javadocs

As an InputStream , your input source, System.in , is indeed Closeable . 作为InputStream ,您的输入源System.in确实是Closeable And once it is closed, it is closed -- nothing further can be read from it, even if you wrap it in a new Scanner . 一旦关闭,它就关闭了-即使将其包装在新的Scanner ,也无法读取任何内容。 This is why your second and subsequent invocations of DataBaseModifier.options() throw. 这就是为什么您对DataBaseModifier.options()第二次和后续调用的原因。

The solution is to avoid closing System.in . 解决方案是避免关闭System.in Moreover, it would be safest to reuse a single Scanner instead of creating a new one, as it is possible for data to be buffered inside the Scanner and lost when you close it. 此外,重用单个Scanner而不是创建新的Scanner将是最安全的,因为可能会将数据缓冲在Scanner内部,并在您关闭Scanner时将其丢失。 There are several ways to approach that problem, but a pretty simple one would be to make your Scanner an instance variable instead of a local variable. 有多种方法可以解决该问题,但是一种非常简单的方法是使Scanner成为实例变量而不是局部变量。 Initialize it when you instantiate the class, and leave it open forever. 在实例化类时初始化它,并使其永远打开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM