面向对象设计控制台持续读取的关键是封装输入逻辑:consoleinput类负责“怎么读”(含语义化方法与异常处理),inputsession类负责“读什么”及流程控制(菜单驱动、状态管理),主程序仅启动会话。

用面向对象设计配合 Scanner 实现控制台持续读取,关键是把输入逻辑封装成可复用、易扩展的对象,而不是把所有代码堆在 main 里。核心思路是:让一个类负责“读什么”,另一个类负责“怎么读”,再用主程序协调流程。
设计一个专门的输入处理器
不要直接在业务逻辑里反复写 scanner.nextLine()。定义一个如 ConsoleInput 类,内部持有 Scanner 实例,并提供语义化方法:
-
readString(String prompt):打印提示,读一行字符串 -
readInt(String prompt):带异常处理,循环直到输入有效整数 -
readDouble(String prompt):同理支持浮点数 -
hasNextLine()或isExitCommand(String input):用于判断是否继续循环
这样业务代码只关心“我要读用户名”,不用操心 try-catch 和空输入校验。
用状态或命令模式管理持续读取流程
持续读取不等于死循环硬写 while(true)。可以设计一个 InputSession 类,它:
- 持有一个
ConsoleInput实例 - 定义一组预设操作(比如 “添加学生”、“查询成绩”、“退出”)
- 用
switch或Map<string runnable></string>把用户输入映射到具体动作 - 每次执行完操作后自动回到主菜单,或根据返回值决定是否继续
例如输入 "quit" 就调用 scanner.close() 并退出循环,其他输入则触发对应功能——逻辑集中,不易遗漏资源释放。
避免 Scanner 的常见陷阱
Scanner 本身不是线程安全的,也不适合多次新建关闭。面向对象封装时要注意:
- 整个应用生命周期内通常只需一个
Scanner实例(绑定System.in),由ConsoleInput独占管理 - 读数字后如果紧接着读字符串,要手动调用
scanner.nextLine()清掉换行符,否则下一次nextLine()会立刻返回空串 - 不要在类中 static 持有
Scanner,容易导致多处误关或资源泄漏
主程序保持简洁,只做启动和收尾
main 方法只需初始化输入处理器和会话,然后启动循环:
public static void main(String[] args) {
ConsoleInput input = new ConsoleInput();
InputSession session = new InputSession(input);
session.start(); // 内部包含 while 循环
}
所有输入解析、错误提示、业务跳转都下沉到对应类中。以后加新功能,只需新增一个 Runnable 或扩展 InputSession 的分支逻辑,无需动主入口。











