Java 之 Charset.defaultCharset()

 简述

以一个故事^1开局。IDEA 在使用 Gradle 时可能会输出乱码,常见的解决方式是 Custom VM Options 里面增加 -Dfile.encoding=UTF-8。但故事作者通过细致分析找到问题的关键,不同系统间的编解码。

以常见的报错信息为例,自 JavacMessage.getLocalizedString(Locale, ...) 诞生, Gradle DaemonPrintStreamLoggingSystem(javac.util.LogPrintWriter) 接收,并使用 StandardOutputListener(TextStreamOutputEventListener) 通过 LogToClient$AsynchronousLogDispatcher 发送该信息,随后StreamBackedStandardOutputListener 吐给 IDEA。但 IDEA 一律按 UTF-8 处理^2,在此处露出了马脚。

当然,这也不是甚问题,因为编码问题由来已久,Intellij Community 在2019年就已经做出选择,specify UTF_8 charset explicitly^3.

Charset.defaultCharset()

java.nio.charset.Charset.defaultCharset()
 /**
 * Returns the default charset of this Java virtual machine.
 *
 * <p> The default charset is determined during virtual-machine startup and
 * typically depends upon the locale and charset of the underlying
 * operating system.
 *
 * @return  A charset object for the default charset
 *
 * @since 1.5
 */
public static Charset defaultCharset() {}

如 defaultCharset() 方法文档所述,该值的确定时间很早,且一般与系统设置有关。

确定时间早,System.initPhase1() 就完成确定,与 GetJavaProperties 有关。

系统,Unix 有 setlocale <language name>_<country name>.<encoding name>,Windows 有 GetLocaleInfo 之类的。

可通过 file.encoding 进行配置。

相关

  1. JEP 226: UTF-8 Property Resource Bundles
  2. JEP 254: Compact Strings
  3. JEP 400: UTF-8 by Default

附加

Unicode 中文乱码速查表(部分)^4

  示例 产生原因
古文码 鐢辨湀瑕佸ソ濂藉涔犲ぉ澶╁悜涓? 以 GBK 方式读取 UTF-8 编码的中文
口字码 ����Ҫ�¨2�ѧϰ������ 以 UTF-8 的方式读取 GBK 编码的中文

Windows UTF-8

  1. Windows 设置 > 时间与语言 > 非 Unicode 程序的语言 > 「Beta版:使用 Unicode UTF-8 提供全球语言支持」
    • 之前开启后,会有 cmd 代码页、USB 复制失败^5等等问题。
    • 现在开启后,暂未遇到。
  2. cmd 设置 code page
    • HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe

参考

  1. https://juejin.cn/post/7194466056940748859
  2. <com/intellij/openapi/externalSystem/util/OutputWrapper.java#L38>
  3. <intellij-community/commit/995b91a5ded47fe4377b8bb2c909ca30cf3d49f4>
  4. <https://github.com/justjavac/unicode-encoding-error-table>
  5. <answers.microsoft.com > 错误0x800700ea:有更多数据可用>

更多

  1. Debugging Gradle internals from IntelliJ IDEA - Damir Murat
  2. How to Debug Your Own IntelliJ IDEA Instance - Vladimír Oraný
posted @ 2023-02-17 21:30  UPeRVv  阅读(293)  评论(0编辑  收藏  举报