System.err 本身不支持颜色,终端是否显示颜色取决于其对 ANSI 转义序列的支持;Linux/macOS、Windows Terminal、Git Bash 默认支持,旧版 cmd.exe 需启用虚拟终端;直接拼接 ANSI 码(如 u001b[31m)即可着色,但需注意重定向和 CI 环境兼容性。

System.err 默认行为不带颜色,终端是否显示颜色取决于自身支持
System.err 本质只是 Java 的一个 PrintStream,它本身不处理颜色;输出到终端后能否变色,完全由终端解释 ANSI 转义序列的能力决定。Linux/macOS 终端、Windows Terminal、Git Bash 通常支持;传统 Windows cmd.exe(旧版)默认不识别,需启用虚拟终端或改用 PowerShell。
直接写 ANSI 转义码是最轻量的着色方式
不需要引入日志框架或额外依赖,只需在写入 System.err 时拼接标准 ANSI 颜色码。例如红色错误提示常用 u001b[31m(前景红),结尾加 u001b[0m 重置样式:
System.err.println("u001b[31mERROR: File not foundu001b[0m");
常见实用组合:
-
u001b[1;31m:加粗 + 红色(适合严重错误) -
u001b[33m:黄色(适合警告) -
u001b[32m:绿色(适合成功提示,虽少用于err,但调试时有用) -
u001b[41m:红色背景(更醒目,但慎用,可能影响可读性)
Windows cmd.exe 下不生效?检查并启用虚拟终端
Java 进程无法控制终端渲染模式,但 Windows 10+ 的 cmd.exe 和 PowerShell 默认关闭 ANSI 支持。必须由启动环境开启:
- PowerShell 中运行:
Set-ItemProperty HKCU:\Console VirtualTerminalLevel -Type DWORD 1 - 或临时启用(程序启动前执行):
System.setProperty("jline.terminal", "jna");(需 jline 依赖,不推荐为颜色加依赖) - 更简单:直接用
Windows Terminal或Git Bash启动你的 Java 程序
验证是否生效:运行 System.err.println("u001b[31mTESTu001b[0m");,若显示为纯文本 TEST 且无乱码,说明终端未启用 ANSI。
避免污染日志或管道输出:检测终端是否为交互式
如果程序可能被重定向(如 java MyApp > out.log 2> err.log),ANSI 码会直接写入文件,造成日志脏数据。应在输出前判断是否连接真实终端:
public static boolean isTerminal() {
return System.console() != null || "true".equals(System.getenv("TERM"));
}
更可靠的做法是检查 System.err 底层是否关联终端设备(需反射或 JNA),但多数场景下加个环境变量开关更实际:
- 启动时加
-Dcolor.stderr=true - 代码中:
if (Boolean.parseBoolean(System.getProperty("color.stderr", "false"))) { /* 加 ANSI */ }
真正麻烦的是跨平台 CI 环境(如 GitHub Actions),其伪终端常不响应 ANSI —— 这时候硬加颜色反而让日志解析失败。










