JVM如何确定Linux上argv的(默认?)字符编码

Java有一个默认的字符编码 ,它在没有明确提供字符编码的上下文中使用。 它如何select编码的文档是模糊的:

默认字符集是在虚拟机启动时确定的,通常取决于底层操作系统的语言环境和字符集。

该文档必须是模糊的,因为JVM使用的方法是系统特定的。

使用默认的字符编码往往是一个坏主意 , 最好使用明确指示的编码,或者对某些I / O始终使用相同的编码。 但是一个不可避免的使用默认字符编码似乎是用于命令行参数的字符编码。 在诸如Linux的POSIX系统上,JVM的本地(C / C ++)代码将命令行参数作为C / C ++ char指针的空终止列表。 这应该被认为是字节指针,因为它们必须以某种(不清楚的)方式编码代码点。 JVM必须解释这些C / C ++ char (字节)序列,将它们转换成一系列Java char ,并赋予Java程序的main() 。 我假设JVM使用默认的字符编码。

因此,我需要准确知道JVM如何确定特定系统(现代GNU / Linux操作系统)的默认编码,因此我可以提供有关我的程序如何运行的用户文档,因此我的程序的用户可以预测它将如何performance。

我猜JVM检查一些环境variables,但哪些?

你可以看看java.nio.charset.Charset.defaultCharset()的源代码。 当我在我的系统(64位Windows 7,Oracle JDK 8更新25)上这样做时,我看到:

 public static Charset defaultCharset() { if (defaultCharset == null) { synchronized (Charset.class) { String csn = AccessController.doPrivileged( new GetPropertyAction("file.encoding")); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; else defaultCharset = forName("UTF-8"); } } return defaultCharset; } 

换句话说,它查看系统属性file.encoding ,如果找不到匹配的Charset实例,则使用UTF-8