字符集问题本身是令人困惑和复杂的,但最重要的是,你必须记住你的字符集的确切名称。是“utf8”吗?或“utf - 8”?或者是“UTF-8”?当你在网上搜索代码样本时,你会看到上面所有的代码。为什么不直接将它们命名为常量并使用Charset.UTF8呢?


当前回答

编码API的当前状态还有待改进。Java 6 API的某些部分不接受Charset来代替字符串(在日志记录中,dom。ls, PrintStream;可能还有其他的)。对于标准库的不同部分,编码应该具有不同的规范名称,这并没有帮助。

我能理解事情是如何发展到现在这个地步的;我不确定我有什么好主意来解决它们。


题外话……

您可以在这里查找Sun的Java 6实现的名称。

对于UTF-8, java的规范值是“UTF-8”。nio和java的“UTF8”。Lang和java.io。该规范要求JRE支持的编码只有:US-ASCII;iso - 8859 - 1;utf - 8;UTF-16BE;UTF-16LE;utf - 16。

其他回答

在Java 1.7中

进口java.nio.charset.StandardCharsets

例: StandardCharsets。UTF_8 StandardCharsets。US_ASCII

我认为我们可以做得更好……为什么不能直接访问保证可用的字符集?字符集。UTF8应该是对字符集的引用,而不是作为字符串的名称。这样我们就不用到处处理UnsupportedEncodingException了。

请注意,我还认为. net选择了一个更好的策略,在所有地方都默认为UTF-8。然后,它把“操作系统默认”编码属性命名为“encoding”,搞砸了。Default -这不是.NET本身的默认值:(

回到对Java字符集支持的咆哮——为什么没有一个用于FileWriter/FileReader的接受字符集的构造函数?基本上,由于这个限制,这些几乎是无用的类-你几乎总是需要一个InputStreamReader来处理fileinputstream或等效的输出:(

护士,护士,我的药呢?

编辑:在我看来,这并没有真正回答这个问题。真正的答案大概是“没有人想到”或者“有人认为这是个坏主意”。我强烈建议,提供名称或字符集的内部实用程序类避免在代码库中重复……或者你也可以用第一次写出这个答案时我们在谷歌处用的那个。(请注意,从Java 7开始,您只需使用StandardCharsets即可。)

我很久以前就用UTF_8、ISO_8859_1和US_ASCII字符集常量定义了一个实用程序类。

此外,很久以前(2年多),我在new String(byte[], Charset)和new String(byte[], String charset_name)之间做了一个简单的性能测试,发现后一种实现要快得多。如果您仔细查看源代码,您会发现它们确实遵循了完全不同的路径。

出于这个原因,我在同一个类中包含了一个实用程序

public static String stringFromByteArray (
    final byte[] array,
    final Charset charset
)
{
    try
    {
        return new String( array, charset.name( ) )
    }
    catch ( UnsupportedEncodingException ex )
    {
        // cannot happen
    }
}

为什么String(byte[], Charset)构造函数不做同样的事情,打败了我。

两年后,Java 7的StandardCharsets现在定义了6个标准字符集的常量。

如果你被Java 5/6卡住了,你可以使用Guava的Charsets常量,就像Kevin Bourrillion和Jon Skeet建议的那样。

编码API的当前状态还有待改进。Java 6 API的某些部分不接受Charset来代替字符串(在日志记录中,dom。ls, PrintStream;可能还有其他的)。对于标准库的不同部分,编码应该具有不同的规范名称,这并没有帮助。

我能理解事情是如何发展到现在这个地步的;我不确定我有什么好主意来解决它们。


题外话……

您可以在这里查找Sun的Java 6实现的名称。

对于UTF-8, java的规范值是“UTF-8”。nio和java的“UTF8”。Lang和java.io。该规范要求JRE支持的编码只有:US-ASCII;iso - 8859 - 1;utf - 8;UTF-16BE;UTF-16LE;utf - 16。