You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java立方体计算程序第二、三实例运行时抛出NoSuchElementException异常求助

问题排查与解决方案

嘿,我一眼就找到你这个NoSuchElementException的根源啦!

为什么会抛出这个异常?

你在getLength()方法里犯了一个常见的错误:每次调用这个方法时,你都新建了一个Scanner实例,并且在方法结束时调用sc.close()。这里的关键是:当你关闭Scanner的时候,它会自动关闭底层关联的System.in输入流——而System.in是全局唯一的,一旦被关闭就再也无法重新打开。

所以第一次创建cube1时,一切正常;但到cube2和cube3调用getLength()时,新的Scanner尝试读取已经被关闭的System.in,自然就抛出NoSuchElementException了。

怎么修复?

我给你推荐两种可行的修复方案,其中第一种是最规范的:

方案1:全局共享一个Scanner(推荐)

创建一个唯一的Scanner实例,在整个程序中复用它,只在程序结束前关闭一次。这样就不会出现关闭System.in的问题了。修改后的代码如下:

import java.util.InputMismatchException;
import java.util.Scanner;
import java.io.*;

public class Cube { // 遵循Java规范,类名首字母大写
    private double side;
    // 定义一个静态Scanner,所有实例共享
    private static Scanner sc = new Scanner(System.in);

    public double getLength(){
        while(true){
            try{
                System.out.println("Please enter an integer: ");
                side = sc.nextDouble();
                break;
            } catch(InputMismatchException e){ // 变量名更有意义
                System.err.println("\nWrong character - please enter a valid number!");
                sc.next(); // 跳过非法输入,避免死循环
                continue;
            }
        }
        // 不要在这里关闭Scanner!
        return side;
    }

    /**
     * 计算立方体的表面积
     * @return 表面积数值
     */
    public double calculateSurfaceArea(){
        return 6 * side * side;
    }

    /**
     * 计算立方体的体积
     * @return 体积数值
     */
    public double calculateVolume(){
        return side * side * side;
    }

    public static void main(String args[]) throws IOException {
        Cube cube1 = new Cube();
        System.out.println("\nSide length of cube1 is " + cube1.getLength());
        System.out.println("Surface Area of cube1 is " + cube1.calculateSurfaceArea());
        System.out.println("Volume of cube1 is " + cube1.calculateVolume());

        Cube cube2 = new Cube();
        System.out.println("\nSide length of cube2 is " + cube2.getLength());
        System.out.println("Surface Area of cube2 is " + cube2.calculateSurfaceArea());
        System.out.println("Volume of cube2 is " + cube2.calculateVolume());

        Cube cube3 = new Cube();
        System.out.println("\nSide length of cube3 is " + cube3.getLength());
        System.out.println("Surface Area of cube3 is " + cube3.calculateSurfaceArea());
        System.out.println("Volume of cube3 is " + cube3.calculateVolume());

        // 程序结束前,统一关闭Scanner
        sc.close();
    }
}

方案2:不在方法内关闭Scanner(临时方案)

如果你不想调整全局结构,也可以直接删除getLength()里的sc.close();语句。这样每个Scanner实例都关联到System.in,虽然不会抛出异常,但会创建多个冗余的Scanner对象,存在潜在的资源泄漏风险,所以不推荐长期使用这个方案。

额外的编码小建议

最后给你提几个Java编码规范的小细节,让代码更专业:

  • 类名必须首字母大写(比如把cube改成Cube)
  • 异常变量名尽量有意义(比如把a改成e或者inputException)
  • 方法注释使用Javadoc格式(/** ... */),方便生成文档和他人阅读

内容的提问来源于stack exchange,提问作者Aureliux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:17:47