Charset问题本身令人困惑和复杂,但最重要的是你必须记住你的字符集的确切名称。是"utf8"
吗?还是"utf-8"
?或者也许"UTF-8"
?在互联网上搜索代码示例时,您将看到以上所有内容。为什么不将它们命名为常量并使用Charset.UTF8
?
答案 0 :(得分:155)
问题的简单答案是可用的字符串字符串因平台而异。
但是,有六个必须存在,所以很久以前就可以做出常数。我不知道为什么他们不是。
通过引入Charset类型,JDK 1.4做得很棒。此时,他们不再需要提供String常量,因为目标是让每个人都使用Charset实例。那么为什么不提供六个标准的Charset常量呢?我问Martin Buchholz,因为他碰巧坐在我旁边,他说没有一个特别好的理由,除了当时的事情仍然是半生不熟的 - 很少有JDK API改装成接受Charset,以及那些,Charset超载通常表现稍差。
令人遗憾的是,只有在JDK 1.6中,他们终于完成了装配Charset重载的所有装备。并且这种倒退的性能情况仍然存在(原因是非常奇怪,我无法解释它,但与安全性有关!)。
长话短说 - 只需定义你自己的常量,或者使用Tony小马链接到的Guava的Charsets类(尽管那个库还没有真正发布)。
更新: StandardCharsets
课程在JDK 7中。
答案 1 :(得分:100)
两年后,Java 7的StandardCharsets现在定义了6个标准字符集的常量。
如果你被困在Java 5/6上,你可以使用Guava的Charsets常量,正如Kevin Bourrillion和Jon Skeet所建议的那样。
答案 2 :(得分:29)
我认为我们可以做得更好......为什么不能直接访问保证可用的字符集? Charset.UTF8
应该是Charset
的引用,而不是字符串的名称。这样我们就不必在整个地方处理UnsupportedEncodingException
。
请注意,我也认为.NET通过在任何地方默认使用UTF-8来选择更好的策略。然后通过命名“操作系统默认”编码属性({1}}来搞砸 - 其中不是 .NET本身的默认值:(
回到关于Java的charset支持的咆哮 - 为什么没有Encoding.Default
/ FileWriter
的构造函数需要FileReader
?基本上,由于这种限制,这几乎是无用的类 - 你几乎总是需要Charset
InputStreamReader
或等效的输出:(
护士,护士 - 我的药在哪里?
编辑:我觉得这并没有真正回答这个问题。真正的答案可能是“没有人参与其中的想法”或“有人参与认为这是一个坏主意”。我强烈建议提供名称或字符集的内部实用程序类避免在代码库周围重复...或者您可以使用the one that we used at Google when this answer was first written。 (请注意,从Java 7开始,您只需使用StandardCharsets
。)
答案 3 :(得分:27)
在Java 1.7中
import java.nio.charset.StandardCharsets
例如:
StandardCharsets.UTF_8
StandardCharsets.US_ASCII
答案 4 :(得分:5)
编码API的当前状态还有待改进。 Java 6 API的某些部分不接受Charset
代替字符串(logging
,dom.ls
,PrintStream
;可能还有其他部分)。编码应该对标准库的不同部分具有不同的规范名称没有帮助。
我能理解事情是如何到达的;我不确定如何解决这些问题。
暂且不说......
您可以查找Sun的Java 6实现here的名称。
对于UTF-8,"UTF-8"
的规范值为java.nio
,"UTF8"
和java.lang
的{{1}}。规范要求JRE支持的唯一编码是: US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16
答案 5 :(得分:2)
我很久以前用UTF_8,ISO_8859_1和US_ASCII Charset常量定义了一个实用程序类。
此外,很久以前(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)构造函数不会这样做,打败了我。