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

Java计算图形面积周长时NoSuchElementException异常修复方案

问题描述

我正在编写一个用于计算圆形与矩形面积、周长的程序,圆形的半径、矩形的宽和长均需从用户输入获取。输入半径参数后,控制台抛出如下异常:

Exception in thread "main" java.util.NoSuchElementException at...

项目包结构说明:

  • Main.java 存放于 main 包
  • Circle.java 与 Rectangle.java 存放于 shapes 包

问题相关代码

Main.java

package main;

import shapes.Circle;
import shapes.Rectangle;

//import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Circle cir = new Circle();
        Rectangle rec = new Rectangle();

        cir.printArea();
        cir.printPerimeter();
        rec.printArea();
        rec.printPerimeter();
    }
}

Circle.java

package shapes;

import java.util.Scanner;

public class Circle {
    final double PI = 3.14;
    double radius;
    double area, perimeter;

    public Circle(double radius) {
        this.radius = radius;
        area = PI*radius*radius;
        perimeter = 2*PI*radius;
    }

    public Circle() {
        System.out.print("radius = ");
        Scanner scan = new Scanner(System.in);
        radius = scan.nextDouble();
        scan.close();
        area = PI*radius*radius;
        perimeter = 2*PI*radius;
    }

    public void printArea() {
        System.out.println("Area of circle = " + area);
    }

    public void printPerimeter() {
        System.out.println("Perimeter of circle = " + perimeter);
    }
}

Rectangle.java

package shapes;

import java.util.Scanner;

public class Rectangle {
    public double length, width;
    double area, perimeter;

    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;

        area = length * width;
        perimeter = (length + width) * 2;
    }

    public Rectangle() {
        Scanner scan = new Scanner(System.in);
        System.out.print("width = ");
        width = scan.nextDouble();
        System.out.print("length = ");
        length = scan.nextDouble();
        scan.close();

        area = length * width;
        perimeter = (length + width) * 2;
    }

    public void printArea() {
        System.out.println("Area of rectangle = " + area);
    }

    public void printPerimeter() {
        System.out.println("Perimeter of rectangle = " + perimeter);
    }
}
异常原因

这个异常的根源是错误关闭了绑定标准输入流System.in的Scanner对象。
Java中所有基于System.in创建的Scanner,共用同一个底层输入流。你在Circle类的无参构造里读完半径就调用scan.close(),这一步会直接把整个System.in流关掉,不是只释放当前Scanner的资源。等后面执行new Rectangle()时,Rectangle构造方法里新创建的Scanner尝试从已经关闭的输入流读取数据,就会抛出NoSuchElementException。

修复方案

核心原则:绑定System.in的Scanner全局只创建一个,不要在局部业务逻辑里随意关闭。

  • 把所有用户输入逻辑从Circle、Rectangle类中移除,统一放到Main类的主方法中处理:全局只创建一个Scanner实例,依次读取圆形半径、矩形宽和长,再把读到的参数传入两个类的有参构造方法创建实例。
  • 所有输入全部读取完成后再统一关闭Scanner,也可以不手动关闭——程序退出时JVM会自动回收相关资源,不会产生资源泄漏。
  • 两个形状类可以直接删掉包含输入逻辑的无参构造,只保留带参数的构造方法、面积周长计算和打印方法即可。

修复后的Main.java代码参考:

package main;

import shapes.Circle;
import shapes.Rectangle;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        // 全局唯一的Scanner实例,绑定标准输入
        Scanner scan = new Scanner(System.in);
        
        System.out.print("radius = ");
        double radius = scan.nextDouble();
        Circle cir = new Circle(radius);
        
        System.out.print("width = ");
        double width = scan.nextDouble();
        System.out.print("length = ");
        double length = scan.nextDouble();
        Rectangle rec = new Rectangle(length, width);
        
        // 所有输入读取完成后再关闭Scanner
        scan.close();

        cir.printArea();
        cir.printPerimeter();
        rec.printArea();
        rec.printPerimeter();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:42:31