关闭main方法的Scanner后新建Scanner抛出NoSuchElementException问题求助
问题分析与解决方案
问题原因
当调用scanner.close()时,不仅会关闭Scanner实例,还会关闭它底层绑定的标准输入流System.in。System.in是全局唯一的输入流,一旦被关闭,整个JVM进程内无法重新打开它。后续在story方法中新建的Scanner试图从已关闭的System.in读取输入,必然抛出NoSuchElementException。
另外代码还有一个隐藏问题:nextInt()和nextDouble()只会读取数字部分,不会处理输入末尾的换行符。如果不提前消耗这个换行符,后续调用nextLine()会直接读取到空字符串,导致逻辑异常。
解决方案
方案1:复用同一个Scanner实例(推荐)
全程使用一个Scanner实例,通过参数传递给story方法,仅在程序结束时统一关闭。同时处理nextDouble()留下的换行符:
package gross_calculator; import java.util.Scanner; public class GrossPayCalculator { static void story(Scanner scanner) { System.out.println("Which season the day is of?"); String season = scanner.nextLine(); System.out.println("How is that day?"); String adjective = scanner.nextLine(); System.out.println("What is the number?"); int number = scanner.nextInt(); System.out.println("On a "+adjective+" "+season+" day,\nyou read "+number+" pages of book."); } public static void main(String[] args) { int hours = 0; System.out.println("How many hours did you work?: "); Scanner scanner = new Scanner(System.in); hours = scanner.nextInt(); double payRate = 0; System.out.println("What is your pay rate?: "); payRate = scanner.nextDouble(); // 消耗nextDouble留下的换行符,避免后续nextLine读空 scanner.nextLine(); double grossPay = hours*payRate; System.out.println("Gross pay: "+grossPay); story(scanner); // 程序结束前统一关闭Scanner scanner.close(); } }
方案2:不关闭关联System.in的Scanner
System.in属于JVM管理的资源,程序退出时会自动关闭,无需手动调用scanner.close()。这种方式下,即使新建Scanner也能正常读取输入,但复用Scanner更符合资源管理规范:
package gross_calculator; import java.util.Scanner; public class GrossPayCalculator { static void story() { System.out.println("Which season the day is of?"); Scanner scanner1 = new Scanner(System.in); // 消耗前一个Scanner留下的换行符 scanner1.nextLine(); String season = scanner1.nextLine(); System.out.println("How is that day?"); String adjective = scanner1.nextLine(); System.out.println("What is the number?"); int number = scanner1.nextInt(); System.out.println("On a "+adjective+" "+season+" day,\nyou read "+number+" pages of book."); } public static void main(String[] args) { int hours = 0; System.out.println("How many hours did you work?: "); Scanner scanner = new Scanner(System.in); hours = scanner.nextInt(); double payRate = 0; System.out.println("What is your pay rate?: "); payRate = scanner.nextDouble(); double grossPay = hours*payRate; System.out.println("Gross pay: "+grossPay); story(); } }
内容的提问来源于stack exchange,提问作者Fatih ağlar
相关产品推荐
相关产品推荐

