Java计算器程序运行报错java.util.NoSuchElementException求助
Java计算器Scanner异常问题:原因与修复方案
错误原因
你遇到的java.util.NoSuchElementException核心原因是:关闭Scanner时会同时关闭底层的System.in标准输入流。
在你的自定义main()方法中,创建Scanner input并调用input.close(),这会彻底关闭System.in流。后续在calculation()及其他运算方法中创建新的Scanner时,因为System.in已经关闭,无法读取任何输入,直接抛出异常。此外,每个方法重复创建Scanner并关闭的写法不仅冗余,还会加剧流关闭的问题。
修复方案
方案1:使用全局单一Scanner实例(推荐)
创建一个全局Scanner实例,在整个程序中复用,仅在程序结束时关闭一次,避免多次关闭System.in。
修改后的完整代码:
import java.util.Scanner; public class Java_Calculator{ // 全局复用的Scanner实例 private static final Scanner scanner = new Scanner(System.in); public static void main(String[] args) { mainMenu(); // 程序结束前关闭Scanner scanner.close(); } // 重命名方法,避免与Java主入口方法重名 static void mainMenu(){ System.out.println("Welcome to Java Calculator!!"); System.out.println("By-theclassicalguy"); System.out.println("<------------------------------------------------------>"); System.out.println("1. Perform a Calculation"); System.out.println("2. Exit"); System.out.println("Enter your choice (1/2):"); int user_choice = scanner.nextInt(); if (user_choice == 1){ calculation(); } else { System.out.println("Thank you for using this program"); } } static void calculation(){ System.out.println("1. Add"); System.out.println("2. Subtract"); System.out.println("3. Multiply"); System.out.println("4. Divide"); System.out.println("Enter your choice (1/2/3/4):"); int choice = scanner.nextInt(); switch(choice){ case 1: add(); break; case 2: sub(); break; case 3: mult(); break; case 4: div(); break; default: System.out.println("Invalid choice!"); } } static void add(){ System.out.println("Enter a number:"); double a = scanner.nextDouble(); System.out.println("Enter a second number"); double b = scanner.nextDouble(); double sum = a + b; System.out.println("The sum is " + sum); } static void sub(){ System.out.println("Enter a number:"); double a = scanner.nextDouble(); System.out.println("Enter a second number:"); double b = scanner.nextDouble(); double difference = a - b; System.out.println("The difference is " + difference); } static void mult(){ System.out.println("Enter a number:"); double a = scanner.nextDouble(); System.out.println("Enter a second number:"); double b = scanner.nextDouble(); double product = a * b; System.out.println("The product is " + product); } static void div(){ System.out.println("Enter numerator:"); double a = scanner.nextDouble(); System.out.println("Enter a denominator"); double b = scanner.nextDouble(); // 增加除数为0的异常防护 if(b == 0){ System.out.println("Error: Denominator cannot be zero!"); return; } double quotient = a / b; System.out.println("The quotient is " + quotient); } }
关键修改点:
- 全局Scanner实例,所有方法共用,不再重复创建
- 删除所有方法内的Scanner创建和
close()调用,仅在主入口最后关闭一次 - 重命名自定义
main()方法为mainMenu(),避免与Java标准主入口方法冲突 - 将
calculation()中的if-else替换为switch语句,提升代码可读性 - 修正运算结果的描述错误(如乘法结果从"sum"改为"product")
- 增加除法的除数为0判断,避免触发
ArithmeticException
方案2:传递Scanner实例
若不想使用全局变量,可以在方法间传递Scanner实例,同样保证流不被重复关闭:
核心代码片段示例:
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); mainMenu(scanner); scanner.close(); } static void mainMenu(Scanner scanner){ // 使用传入的scanner读取输入,不关闭 int user_choice = scanner.nextInt(); if (user_choice == 1){ calculation(scanner); } } static void calculation(Scanner scanner){ int choice = scanner.nextInt(); switch(choice){ case 1: add(scanner); break; // 其他运算方法同理,传递scanner实例 } } static void add(Scanner scanner){ double a = scanner.nextDouble(); double b = scanner.nextDouble(); // 计算逻辑... }
内容的提问来源于stack exchange,提问作者Aaron Thomas Cherian
相关产品推荐
相关产品推荐

