Java:为什么字符集名称不是常量?
字符集问题本身就是令人困惑和复杂的,但最重要的是,您必须记住您的字符集的确切名称。 它是"utf8"
吗? 或"utf-8"
? 或者也许"UTF-8"
? 当search代码样本的互联网,你会看到以上所有。 为什么不把它们命名为常量并使用Charset.UTF8
?
要问的问题的简单答案是可用的charsetstring因平台而异。
然而,有六个是需要在场的,所以常常可以在很久以前做出。 我不知道他们为什么不是。
通过引入字符集types,JDK 1.4做了一件好事。 在这一点上,他们不会想要提供string常量,因为目标是让每个人都使用Charset实例。 那么为什么不提供六个标准的Charset常量呢? 我问过Martin Buchholz,因为他碰巧坐在我旁边,他说除了当时还没有完成,还没有什么特别的原因,JDK API已经过时了,接受字符集,而Charset的超载通常会稍差一些。
很遗憾,只有在JDK 1.6中,他们终于完成了Charset过载的所有工作。 而这种倒退的performance情况依然存在(之所以令人难以置信的奇怪,我无法解释,但与安全有关!)。
长话短说 – 只需定义你自己的常量,或者使用托马小马链接到的番石榴的字符类(尽pipe这个库实际上还没有真正发布)。
更新: StandardCharsets
类在JDK 7中。
两年后,Java 7的StandardCharsets现在定义了6个标准字符集的常量。
如果你被困在Java 5/6上,你可以使用Guava的Charsets常量,正如Kevin Bourrillion和Jon Skeet所build议的那样。
我认为我们可以做得比这更好……为什么不能直接访问保证可用的字符集呢? Charset.UTF8
应该是对Charset
的引用,而不是string的名称。 这样我们就不必处理UnsupportedEncodingException
。
请注意,我也认为.NETselect了一个更好的策略,就是在任何地方都默认使用UTF-8。 然后通过命名“操作系统默认”编码属性简单地Encoding.Default
– 这不是默认的.NET本身:(
回到关于Java的字符集支持的咆哮 – 为什么没有一个FileWriter
/ FileReader
的构造函数需要一个Charset
? 基本上这些几乎是无用的类,由于这个限制 – 你几乎总是需要一个InputStreamReader
FileInputStream
或等价的输出:(
护士,护士 – 我的药在哪里?
编辑:它发生在我这并没有真正回答这个问题。 真正的答案大概是“没有人想到它”或者“有人认为这是一个坏主意”。 我强烈build议提供名称或字符集的内部实用程序类避免代码库中的重复…或者您可以使用我们在Google上使用的那个 。
在Java 1.7中
import java.nio.charset.StandardCharsets
例如: StandardCharsets.UTF_8
StandardCharsets.US_ASCII
编码API的当前状态留下了一些需要的东西。 Java 6 API的某些部分不接受string代替string(在logging
, dom.ls
, PrintStream
;可能还有其他部分)。 对于标准库的不同部分,编码应该有不同的规范名称。
我可以理解事情到底是怎么回事。 不知道我有什么好的想法如何解决这些问题。
作为旁白…
您可以在这里查找Sun的Java 6实现的名称。
对于UTF-8, java.nio
的规范值为"UTF-8"
"UTF8"
, java.lang
和java.io
的规范值为"UTF8"
。 规范中唯一需要JRE支持的编码是: US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16 。
我很久以前就定义了一个UTF_8,ISO_8859_1和US_ASCII字符集常量的工具类。
另外,很久以前(2年以前),我在new String( byte[], Charset )
和new String( byte[], String charset_name )
之间做了一个简单的性能testing,发现后者的实现更快。 如果你仔细观察源代码,你会发现它们确实遵循了不同的path。
出于这个原因,我在同一个class上加了一个实用工具
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)的构造函数不能做同样的事情,我打败了。