Answers:
对所提问题的简单回答是,可用的字符集字符串因平台而异。
但是,必须存在六个,因此对于那些很早以前就可以建立常数。我不知道为什么他们没有。
JDK 1.4通过引入Charset类型做了一件了不起的事情。在这一点上,他们不再想要提供String常量,因为目标是让所有人都使用Charset实例。那么,为什么不提供六个标准的Charset常数呢?我问马丁·布赫霍尔茨(Martin Buchholz),因为他刚好就坐在我旁边,他说并没有什么特别重要的理由,除了那个时候事情还不成熟–很少有JDK API可以改装接受Charset,在其中的一个中,Charset重载通常执行得稍差一些。
令人遗憾的是,直到最后在JDK 1.6中,他们才最终为所有组件配备了Charset重载。而且这种落后的性能状况仍然存在(之所以令人难以置信的怪异,我无法解释,而是与安全性相关!)。
长话短说-只需定义您自己的常量,或使用Guad的Charsets类(与Tony the Pony关联)即可(尽管该库尚未真正发布)。
更新:StandardCharsets
JDK 7中有一个类。
String(byte bytes[], int offset, int length, Charset charset)
的实现方式。实际上,从大字节[]创建小字符串时,性能的提高一点也不微不足道。
两年后,Java 7的StandardCharsets现在为6个标准字符集定义了常量。
如果您坚持使用Java 5/6,则可以按照Kevin Bourrillion和Jon Skeet的建议使用Guava的Charsets常量。
我认为我们可以做得更好……为什么不能直接访问保证可用的字符集?Charset.UTF8
应该是对的引用Charset
,而不是作为字符串的名称。这样,我们就不必在UnsupportedEncodingException
所有地方处理。
提醒您,我还认为.NET通过在各处默认使用UTF-8来选择更好的策略。然后,通过简单地命名“操作系统默认”编码属性来搞砸Encoding.Default
-这不是 .NET本身的默认属性:(
回到对Java的字符集支持的狂热-为什么不为FileWriter
/ 构造FileReader
一个需要一个Charset
?的构造函数?基本上,由于这种限制,那些几乎是无用的类-您几乎总是需要InputStreamReader
a FileInputStream
或等效的输出:(
护士,护士-我的药在哪里?
编辑:我想到这还没有真正回答问题。真正的答案大概是“没有人想到它”或“有人认为这是个坏主意”。我强烈建议提供名称或字符集的内部实用程序类避免在代码库中重复...否则,您可以使用在首次编写此答案时在Google上使用的那种实用程序。(请注意,从Java 7开始,您只需使用它即可StandardCharsets
。)
编码API的当前状态有待改进。Java 6的API的某些部分不接受Charset
代替字符串(在logging
,dom.ls
,PrintStream
,有可能是其他人)。对于标准库的不同部分,编码应该具有不同的规范名称无济于事。
我能理解事物是如何到达的。不确定我对如何解决它们有任何出色的想法。
作为旁白...
您可以在此处查找Sun的Java 6实现的名称。
对于UTF-8,规范值为"UTF-8"
for java.nio
和"UTF8"
for java.lang
和java.io
。规范要求JRE支持的唯一编码是:US-ASCII;ISO-8859-1;UTF-8;UTF-16BE; UTF-16LE; UTF-16。
我很久以前用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)构造函数不做同样的事情,让我感到震惊。
Charset
无须注册,所以异常可能发生。IIRC,JDK7中进行了一些更改,以使其更快地用于已知良好的Charset
实现(消除多余的副本)。
MessageDigest#getInstance()
顺便说说同样的故事。