JDK 18 及以上使用标准输出流中文输出乱码问题
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://stazxr.cn/2024/12/05/JDK-18-以上使用标准输出流中文输出乱码问题/
来源:終わり群星
问题描述
起因是 tomcat 调用servlet输出的System.out.println(也就是所说的控制台输出流)中文乱码,但是其他输出没有受到影响。
问题分析
运行环境:JDK 21, Tomcat 10
我所有的代码都是UTF-8编码的,而且在IDEA中设置了UTF-8编码。
并且Tomcat也配置了-Dfile.encoding=UTF-8选项
通过查看System.out的编码方式,发现是GBK,但是在控制台的编码方式是UTF-8。
System.out.println(System.out.charset()); // System.out.charset()方法自jdk18起
// output: GBK
使用jdk17的时候没有问题,但是使用jdk21就会出现乱码问题。
解决方案
参考JEP 400: UTF-8 by Default (openjdk.org)通过调用getProperty方法获取默认字符集
System.out.println("Java Runtime version " + System.getProperty("java.runtime.version"));
System.out.println("----------------------------------------------------------");
//全局默认编码 JDK21是UTF
System.out.println("Charset.defaultCharset() = " + Charset.defaultCharset());
//默认文件的编码,这个应该是字节码文件
System.out.println("System.getProperty(\"file.encoding\") = " + Charset.defaultCharset().displayName());
//获取的是本地的字符集编码,中文windows系统应该是GBK
System.out.println("System.getProperty(\"native.encoding\") = " + System.getProperty("native.encoding"));
System.out.println("System.getProperty(\"sun.jnu.encoding\") = " + System.getProperty("sun.jnu.encoding"));
//这个是输出流的默认字符集编码
System.out.println("System.getProperty(\"sun.stdout.encoding\") = " + System.getProperty("sun.stdout.encoding"));
//这个是错误流的默认编码
System.out.println("System.getProperty(\"sun.stderr.encoding\") = " + System.getProperty("sun.stderr.encoding"));
//console默认编码
System.out.println("System.console().charset() = " + System.console().charset());
//当前输出流的编码
System.out.println("System.out.charset() = " + System.out.charset());
System.out.println("----------------------------------------------------------");
在一般的情况下System.getProperty("sun.stdout.encoding")和System.getProperty("sun.stderr.encoding")的值是UTF-8,但是在Tomcat中是null。
tomcat 10 不会指定输出流的字符编码
所以我们需要在启动tomcat的时候指定输出流的字符编码
是在启动配置中的 VM options 添加参数:
-Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8
这种方法只能解决所设置程序的编码问题,若需解决 Javadoc 的乱码,则需在-D前添加-J。
-J-Dstdout.encoding=UTF-8 -J-Dstderr.encoding=UTF-8
总结
乱码问题只出现在jdk18及以上的版本,因为Java 18 中将默认编码改为了 UTF-8,但没有改动System.out和System.err的编码。
所以使用jdk17没有问题,但是在使用jdk21就会出现乱码问题。
只要在 VM options 中添加 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 即可设置输出流的编码。
参考
- JEP 400: UTF-8 by Default (openjdk.org)
- https://openjdk.java.net/jeps/400
- 解决 Java 18 以上 IDEA 中文输出乱码问题(知乎)
- 解决IDEA控制台中输出中文乱码并探究原因(JDK18及以上)
写在最后

JDK 18 及以上使用标准输出流中文输出乱码问题的更多相关文章
- 解决VS Code编译调试中文输出乱码
最近尝试用VS Code配置了C和C++的编译调试环境,结果遇到了中文输出乱码问题,查阅网上竟然还没有相关问题,有怀疑是mingw中文支持问题,但最后证明是VS Code编码问题. 解决方案: 文件- ...
- qtcreator_process_stub中文输出乱码
使用qt运行程序输出中文,全都变成了□,让人很头疼,百度了很久,找了一些解决方案都是: 用vim打开x11-common,在控制台输入 vim /etc/X11/Xresources/x11-comm ...
- 控制台程序的中文输出乱码问题(export LC_CTYPE=zh_CN.GBK,或者修改/etc/sysconfig/i18n为zh_CN.GBK。使用setlocale(LC_CTYPE, "");会使用默认办法。编译器会将源码做转换成Unicode格式,或者指定gcc的输入文件的编码参数-finput-charset=GBK。Linux下应该用wprintf(L"%ls/n",wstr))
今天发现用securecrt登陆时,gcc编译出错时会出现乱码,但直接在主机的窗口界面下用Shell编译却没有乱码.查看了一下当时的错误描述,发现它的引号是中文引号,导致在SecureCRT中显示出错 ...
- python--ulipad控制台中文输出乱码
ulipad用起来顺手,而不尽人意的地方时,它不能正确输出中文.而且有人指出这和文件的编码没关系,所以将”设置“选项里”缺省文档编码“修改为”utf-8“也无济于事.为了解决这个问题,我在网上搜了搜, ...
- Code:Blocks中文输出乱码解决方法
0x01 问题描述 将CB的编码格式设置为UTF-8之后,在CMD窗口输出中文乱码. 0x02 解决办法 控制台显示的时候缺省的是使用系统默认的字符集,比如windows下用的是GBk,但是默认情况下 ...
- Sublime + Python3 + 虚拟环境 + 去除 中文输出乱码
MacBook Pro Retina 13 2013年底版 所用软件 1. Sublime Text 3安装 Virtualenv package 2. 用 iterm2 .或者终端安装zip:apt ...
- windows下解决PyCharm控制台中文输出乱码
我用的PyCharm是2018.2版本 在调用os.system()的过程中遇到了控制台中文乱码的问题,具体如下 网上说的将两个Encoding格式都设置为UTF-8并没有解决问题,后来我将Proje ...
- python3中文输出乱码的问题
最近使用you-get这个工具下载视频,发现命令行窗口里显示的媒体标题是乱码(但文件管理器里显示正常).我的命令行窗口的code page是936,sys.stdout.encoding是utf-8, ...
- Java控制台中输入中文输出乱码的解决办法
Run---Run Configurations---Common---Encoding---Other---GBK Run Configurations里的Common中将编码方式改成GBK就正常了
- Jenkins控制台中文输出乱码解决方法
1. 设置jenkins所在服务器环境变量,右键我的电脑→属性→高级系统设置→环境变量,添加JAVA_TOOL_OPTIONS 2.修改Tomcat配置,进入apache_tomcat/conf文件夹 ...
随机推荐
- 神经网络之卷积篇:详解为什么使用卷积?(Why convolutions?)
详解为什么使用卷积? 来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集训练卷积神经网络做个简单概括.和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀 ...
- Nuxt.js 应用中的 app:mounted 钩子详解
title: Nuxt.js 应用中的 app:mounted 钩子详解 date: 2024/10/5 updated: 2024/10/5 author: cmdragon excerpt: ap ...
- USB LFPS是什么?
USB LFPS:低功耗状态下的高速数据传输 什么是USB LFPS? USB LFPS(Low-Power Signaling)指的是USB接口在低功耗状态下的一种高速数据传输技术.传统上,USB接 ...
- Android dex、odex、oat、vdex、art区别
1.dex java程序编译成class后,dx工具将所有class文件合成一个dex文件,dex文件是jar文件大小的50%左右. 2.odex(Android5.0之前)全称:Optimized ...
- electron 菜单选项 - 隐藏,设置菜单
隐藏菜单 const { app, Menu, session } = require('electron'); /*隐藏electron的菜单栏*/ Menu.setApplicationMenu( ...
- 21 如何写出一篇高质量的sci水文
博客配套视频链接: https://www.bilibili.com/video/BV1fW4y1W7dS/ b 站直接看 模型确定, 结果正在跑(或已结束), 目标期刊已定,一般可以定顶刊 从目标期 ...
- kotlin集合——>集合操作概述、集合转换
1. 集合操作概述: Kotlin 标准库提供了用于对集合执行操作的多种函数.这包括简单的操作,例如获取或添加元素,以及 更复杂的操作,包括搜索.排序.过滤.转换等 1.1 扩展与成员函数 集合操作在 ...
- SpringBoot进阶教程(八十二)Spring Security图形验证码
在之前的博文<SpringBoot进阶教程(八十)Spring Security>中,已经介绍了在Spring Security中如何基于formLogin认证.基于HttpBasic认证 ...
- 在 OpenFunction 中运行 Serverless 应用
除了构建和运行 Serverless 函数之外,OpenFuntion 还支持构建和运行 Serverless 应用.因此,OpenFunction 用户可以不用局限在各语言的 functions-f ...
- 搞清楚这个老六的真面目!逐层‘剥开’人工智能中的卷积神经网络(CNN)
第三章:超越基础--图像中的特征检测 上一篇<揭开计算机视觉的神秘面纱,原来机器是这样"看图"的!> 本篇序言:上一篇我们实现并训练了一个神经网络,成功让计算机&quo ...