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

Java项目中打开并关闭两个不同Scanner的问题排查

问题分析与解决方案

首先我先把你给出的代码补全(看起来是输入到一半截断了),方便更清晰地理解场景:

package scannerDebug; 
import java.util.Scanner; 

public class Class1 { 
    private String name_; 

    public Class1(String name) { 
        name_ = name; 
    } 

    public static void main(String[] args) { 
        Scanner in = new Scanner(System.in); 
        System.out.print("Enter name: ");
        String inputName = in.nextLine();
        Class1 obj = new Class1(inputName);
        // 如果执行这行,后续再用Scanner读取System.in就会报错
        in.close();
    }
}

问题根源

你碰到的是个非常典型的Scanner使用误区:当你关闭和System.in绑定的Scanner时,它会顺带把底层的System.in输入流也一起关闭。而System.in是JVM进程级别的全局资源,一旦关闭就没法重新打开,这就导致后续任何尝试读取System.in的代码都会抛出异常。

修改变量名没用,因为问题核心根本不是变量名,而是System.in流被提前关闭了。

解决方案

针对这个场景,有两个实用的处理方式:

  • 不要手动关闭和System.in关联的Scanner:System.in由JVM负责管理,当JVM退出时会自动释放这个资源,完全不需要我们手动调用close()。这是最简单直接的解决办法,也是官方推荐的做法。
  • 使用全局单例Scanner:如果你的项目需要在多个类、多个方法中读取控制台输入,建议创建一个全局的Scanner实例,整个应用生命周期内复用它,避免重复创建和关闭操作。示例代码如下:
package scannerDebug;
import java.util.Scanner;

public class ScannerSingleton {
    private static final Scanner INSTANCE = new Scanner(System.in);

    private ScannerSingleton() {} // 私有构造,禁止外部实例化

    public static Scanner getInstance() {
        return INSTANCE;
    }
}

// 其他类中调用示例
public class Class1 {
    private String name_;

    public Class1(String name) {
        name_ = name;
    }

    public static void main(String[] args) {
        Scanner in = ScannerSingleton.getInstance();
        System.out.print("Enter name: ");
        String inputName = in.nextLine();
        Class1 obj = new Class1(inputName);
        // 全程不需要关闭,整个应用共用这一个实例
    }
}

这样既避免了关闭流导致的异常问题,也保证了资源的合理复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:53:10