回答:
質問に対する簡単な答えは、使用可能な文字セット文字列はプラットフォームごとに異なるということです。
ただし、存在する必要があるのは6つなので、定数はずっと前に作成されている可能性があります。彼らがそうでなかった理由がわかりません。
JDK 1.4は、Charsetタイプを導入することで素晴らしい成果を上げました。この時点では、Charsetインスタンスを使用して全員を取得することを目的としているため、もはやString定数を提供する必要はありませんでした。それでは、なぜ6つの標準Charset定数を提供しないのでしょうか。マーティンブーフホルツがたまたま私の隣に座っているので、彼に尋ねたところ、当時特に問題はなかったということを除いて、それほど大きな理由はなかったと述べました。 Charsetを受け入れます。Charsetのオーバーロードは通常、わずかにパフォーマンスが低下しました。
JDK 1.6でのみ、Charsetオーバーロードを備えたすべてのものが最終的に装備されたのは残念です。そして、この逆方向のパフォーマンス状況はまだ存在しています(理由は信じられないほど奇妙で説明できないのですが、セキュリティに関連しています!)。
要するに、独自の定数を定義するか、Tony the PonyがリンクしているGuavaのCharsetsクラスを使用するだけです(そのライブラリはまだ実際にはまだリリースされていません)。
アップデート:StandardCharsets
このクラスは、JDK 7です。
String(byte bytes[], int offset, int length, Charset charset)
実装方法の省略/無視です。実際、大きなbyte []から小さな文字列を作成する場合、パフォーマンスへの影響はそれほど大きくありません。
2年後、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文字セット定数を使用してユーティリティクラスを定義しました。
また、(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、既知の良好なCharset
実装(余分なコピーを排除)を高速化するためにJDK7にいくつかの変更がありました。
MessageDigest#getInstance()
ちなみに同じ話が続きます。