如何确保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
相关产品推荐
相关产品推荐

