【问题标题】:How does the JVM determine the (default?) character encoding for argv on LinuxJVM 如何确定 Linux 上 argv 的(默认?)字符编码
【发布时间】:2015-03-11 11:32:54
【问题描述】:

Java 有一个default character encoding,它在未明确提供字符编码的上下文中使用。 如何它选择编码的文档是模糊的:

默认字符集在虚拟机启动期间确定,通常取决于底层操作系统的区域设置和字符集。

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

使用默认的字符编码往往是a bad idea;最好使用明确指定的编码,或者对某些 I/O 始终使用相同的编码。但是默认字符编码的一种不可避免的使用似乎是用于命令行参数的字符编码。在诸如 Linux 的 POSIX 系统上,JVM 的本机 (C/C++) 代码将命令行参数作为 C/C++ char 指针的空终止列表获取。应该将其视为字节指针,因为它们必须在some (unclear) manner 中编码代码点。 JVM 必须解释这些 C/C++ chars(字节)序列,以将它们转换为 Java 序列 chars,以提供给 Java 程序的 main()。我假设 JVM 为此使用默认字符编码。

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

我猜 JVM 会检查一些环境变量,但是哪些?

【问题讨论】:

标签: java linux character-encoding environment


【解决方案1】:

当然可以看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

【讨论】:

  • 这意味着doc of Charset.defaultCharset() 有点不精确,因此如果不使用-Dfile.encoding 标志,它只会使用UTF-8,而不需要从底层读取任何内容吗?参见文档:“在虚拟机启动期间确定,通常取决于底层操作系统的语言环境和字符集”。
  • @Mabsten 不一定。我怀疑在 JVM 的某个地方有一个默认设置 file.encoding,如果你没有用 -D 明确设置它,就会使用它。该默认值取决于您使用的操作系统。
猜你喜欢
  • 2010-11-03
  • 2018-10-04
  • 2011-07-08
  • 2011-07-27
  • 1970-01-01
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多