web-dev-qa-db-ja.com

文字セット名が定数ではないのはなぜですか?

文字セットの問題はそれ自体で混乱を招き、複雑になりますが、それに加えて、文字セットの正確な名前を覚えておく必要があります。 "utf8"ですか?または"utf-8"?それとも"UTF-8"?コードサンプルをインターネットで検索すると、上記のすべてが表示されます。なぜそれらを名前付き定数にし、Charset.UTF8を使用しないのですか?

208
serg

質問に対する簡単な答えは、利用可能な文字セット文字列がプラットフォームごとに異なるということです。

ただし、存在する必要があるのは6つであるため、ずっと前から定数を作成できた可能性があります。なぜそうではなかったのか分かりません。

JDK 1.4は、Charset型を導入することで素晴らしいことをしました。この時点では、Charsetインスタンスを使用して全員を取得することが目標なので、文字列定数をもう提供したくありませんでした。それでは、なぜ6つの標準Charset定数を提供しないのですか?マーティン・ブッフホルツに尋ねたところ、彼は私の隣に座っていたので、特にそれほど大きな理由はなかったと言いましたが、当時はまだ中途半端だったということを除いて、JDK APIが改造されていませんでしたCharsetを受け入れますが、Charsetのオーバーロードは通常わずかに悪化しました。

JDK 1.6でのみ、Charsetのオーバーロードですべてを装備し終えたのは悲しいことです。そして、この後方のパフォーマンス状況がまだ存在していること(その理由は信じられないほど奇妙であり、私はそれを説明することはできませんが、セキュリティに関連しています!).

簡単に言えば、独自の定数を定義するか、Tony the PonyがリンクしたGuavaのCharsetsクラスを使用します(実際にはまだライブラリはリリースされていません)。

更新:a StandardCharsets クラスはJDK 7にあります。

157

2年後、Java 7の StandardCharsets は6つの標準文字セットの定数を定義するようになりました。

Java 5/6にこだわっている場合、Kevin BourrillionとJon Skeetが示唆するように、Guavaの Charsets 定数を使用できます。

101
Etienne Neveu

私はそれよりもはるかに良いことができると主張します...なぜ保証された利用可能な文字セットが直接アクセスできないのですか? Charset.UTF8は、文字列としての名前ではなく、Charsetへの参照である必要があります。そうすれば、UnsupportedEncodingExceptionをあちこちで処理する必要がなくなります。

念のために言っておきますが、.NETは、デフォルトでどこでもUTF-8を使用することで、より良い戦略を選択したと思います。次に、「オペレーティングシステムのデフォルト」エンコーディングプロパティに単にEncoding.Defaultという名前を付けることで失敗しました。これは.NET内のデフォルトではありません。 (

Javaの文字セットサポートについて暴言に戻る-なぜFileWriterを取るFileReader/Charsetのコンストラクターがないのですか?基本的に、これらの制限のためにほとんど役に立たないクラスです-ほとんどの場合、InputStreamReaderの周りにFileInputStreamまたは同等の出力が必要です:(

看護師、看護師-私の薬はどこですか?

編集:私はこれが本当に質問に答えていないことがわかります。本当の答えは、おそらく「だれもそれについて考えなかった」または「だれかが悪い考えだと思った」のいずれかです。名前または文字セットを提供する社内ユーティリティクラスは、コードベースでの重複を避けることを強くお勧めします...または、単に この回答が最初に書かれたときにGoogleで使用したもの を使用することもできます。 (Java 7の時点で、代わりに StandardCharsets を使用することに注意してください。)

29
Jon Skeet

Java 1.7で

import Java.nio.charset.StandardCharsets

例:StandardCharsets.UTF_8StandardCharsets.US_ASCII

27
Roger

エンコーディングAPIの現在の状態では、何かが望まれます。 Java 6 APIの一部は、文字列の代わりにCharsetを受け入れません(loggingdom.lsPrintStream;その他)。エンコーディングが標準ライブラリの異なる部分に対して異なる標準名を持つことになっているのは役に立ちません。

私は、物事がどこに着いたかを理解できます。それらを修正する方法について素晴らしいアイデアがあるかどうかわかりません。


余談として...

SunのJava 6実装の名前を検索できます here

UTF-8の場合、正規値は"UTF-8"の場合はJava.nio"UTF8"およびJava.langの場合はJava.ioです。仕様がサポートするためにJREを必要とする唯一のエンコーディングは次のとおりです:US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16

5
McDowell

私はずっと前に、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)コンストラクターが同じことをしないのはなぜですか。