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

如何确保KeyboardScanner类仅创建一个Scanner实例?构造器判断失效求助

问题分析

你当前的代码无法限制Scanner实例数量的核心原因是:inputStreamExists是实例变量,每个新创建的KeyboardScanner对象都会独立初始化这个变量为false,所以每次调用构造器都会进入创建Scanner的分支,完全起不到限制作用。

当你尝试把inputStreamExists设为static后无法创建实例,大概率是因为测试代码中已经创建过KeyboardScanner实例,导致静态变量inputStreamExists被设为true,后续创建时直接触发异常;或者是修改时破坏了初始化逻辑。

解决方案

要实现“最多仅创建一个Scanner实例”的需求,需要把Scanner和状态标志都设为静态变量(属于类本身,所有实例共享),同时调整构造器逻辑。以下是两种可行方案:

方案1:保留原有构造器,通过静态变量控制Scanner初始化

修改后的完整代码:

import java.util.Scanner;
import java.io.InputStream;

public class KeyboardScanner {

    // 静态变量:所有实例共享同一个Scanner和状态标志
    private static Scanner scanner;
    private static boolean inputStreamExists = false;

    public KeyboardScanner(InputStream inputStream) {
        if (!inputStreamExists) {
            scanner = new Scanner(inputStream);
            inputStreamExists = true;
        } else {
            throw new IllegalArgumentException("Scanner already exists.");
        }
    }

    public KeyboardScanner() {
        this(System.in);
    }

    public int setInt(String ledtext) {
        System.out.print(ledtext + " ?>");
        int a = scanner.nextInt();
        scanner.nextLine();
        return a;
    }

    public double setDouble(String ledtext) {
        System.out.print(ledtext + " ?>");
        double b = scanner.nextDouble();
        scanner.nextLine();
        return b;
    }

    public String setString(String ledtext) {
        System.out.print(ledtext + " ?>");
        String s = scanner.nextLine();
        return s;
    }
}

这样所有KeyboardScanner实例都会共用同一个Scanner,且只有第一次创建对象时会初始化Scanner,后续创建会抛出异常。

方案2:使用单例模式(更规范的实现)

如果你希望整个程序中只有一个KeyboardScanner实例(自然只有一个Scanner),可以把构造器设为私有,通过静态方法获取实例:

import java.util.Scanner;
import java.io.InputStream;

public class KeyboardScanner {

    private static Scanner scanner;
    private static KeyboardScanner instance;

    // 私有构造器,禁止外部直接new对象
    private KeyboardScanner(InputStream inputStream) {
        scanner = new Scanner(inputStream);
    }

    // 获取默认实例(使用System.in)
    public static KeyboardScanner getInstance() {
        return getInstance(System.in);
    }

    // 获取指定输入流的实例
    public static KeyboardScanner getInstance(InputStream inputStream) {
        if (instance == null) {
            instance = new KeyboardScanner(inputStream);
        }
        return instance;
    }

    public int setInt(String ledtext) {
        System.out.print(ledtext + " ?>");
        int a = scanner.nextInt();
        scanner.nextLine();
        return a;
    }

    public double setDouble(String ledtext) {
        System.out.print(ledtext + " ?>");
        double b = scanner.nextDouble();
        scanner.nextLine();
        return b;
    }

    public String setString(String ledtext) {
        System.out.print(ledtext + " ?>");
        String s = scanner.nextLine();
        return s;
    }
}

使用时直接调用KeyboardScanner.getInstance()获取实例,无需手动new,彻底避免重复创建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:55:18