java - 为什么我会收到 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();
}
解决方案
扩展和澄清 user3170251 的评论,Scanner
如果该源实际上是,则关闭 a 也会关闭基础数据源Closeable
:
如果这个扫描器还没有关闭,那么如果它的底层可读也实现了 Closeable 接口,那么可读的 close 方法将被调用。如果此扫描仪已关闭,则调用此方法将无效。
作为一个InputStream
,您的输入源System.in
确实是Closeable
。一旦它关闭,它就关闭了——即使你将它包装在一个新的Scanner
. 这就是您第二次和后续调用DataBaseModifier.options()
throw 的原因。
解决办法是避免关闭System.in
。此外,重用单个Scanner
而不是创建一个新的将是最安全的,因为数据可能会在内部缓冲Scanner
并在您关闭它时丢失。有几种方法可以解决这个问题,但一种非常简单的方法是让你Scanner
的实例变量而不是局部变量。在实例化类时初始化它,并让它永远打开。
推荐阅读
- python - Conda 安装时间过长
- c# - 迁移到 ASP Core 3.1 后,控制台中的 Razor MVC 无法正常工作
- git-checkout - Git 从 master 分支拉到另一个分支
- loopbackjs - LOOPBACK 4:将环回 Cli 升级到最新版本,当 URL 被过滤器和偏移量命中时,会收到 BAD REQUEST
- session - 使用条带时管理 Flask 会话
- scala - 异步行为测试 akka
- nanoframework - NanoFramework 上的套接字连接
- sql-server - 禁用 SA,创建新登录,将数据库角色成员更改为数据库所有者
- hl7-fhir - _include 在 hapi fhir 中
- sql - 如何在 SQL 中将 NOT IN 语句转换为 NOT EXISTS 语句?