推荐使用Console.readPassword()隐藏密码输入,它不回显字符且返回可清空的char[];IDE中System.console()常为null,需降级用Scanner逐字符覆盖模拟隐藏,并及时清空数组防内存泄露。

Java 从控制台接收密码时,默认的 Scanner 或 BufferedReader 会明文显示用户输入,存在安全风险。Java 提供了 Console.readPassword() 方法,它能隐藏输入内容(不回显字符,也不换行),是标准且推荐的做法。
使用 Console.readPassword() 获取隐藏密码
这是最简单、最安全的方式,适用于命令行环境(非 IDE 的运行终端):
-
System.console()在支持控制台的环境中返回Console对象;在某些 IDE(如 IntelliJ、Eclipse)中可能返回null,此时需降级处理 -
readPassword()返回char[],比String更安全(可手动清空内存) - 输入结束后自动换行,无需额外
System.out.println()
示例代码:
Console console = System.console();
if (console != null) {
char[] password = console.readPassword("请输入密码: ");
// 使用完后立即清空数组
if (password != null) {
Arrays.fill(password, '\0');
}
} else {
System.out.println("控制台不可用,无法隐藏输入");
}
IDE 中无法使用 Console 的替代方案
多数 IDE 的模拟终端不支持 Console,此时只能退而求其次:用 Scanner 明文读取,但通过覆盖光标位置“视觉上”隐藏——这并非真正安全,仅作提示性遮掩(适合教学或本地调试):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 逐字符读取
System.in.read(),遇到回车(\r或\n)停止 - 每输入一个字符,输出
\b \b(退格+空格+退格)来擦除,再打印星号* - 注意:不能完全防止命令行历史或进程参数泄露,仅改善用户体验
重要安全提醒
无论用哪种方式,都应注意:
- 避免将密码存为
String:字符串不可变,可能长期留在内存中;优先用char[]并及时清空 - 生产环境建议使用成熟认证框架(如 Spring Security),而非手写密码输入逻辑
- 图形界面应用应使用
JPasswordField,它原生支持隐藏显示
小结
标准做法是 Console.readPassword();IDE 调试时若失败,可临时用字符覆盖模拟隐藏;始终优先清理敏感字符数组,不依赖 GC。

















