23

Java SE 7 仕様によると、 Javaは Unicode UTF-16 標準を使用して文字を表現します。それぞれが 1 文字を含む 16 ビット変数の単純な配列Stringとして a を想像すると、人生は単純です。

残念ながら、16 ビットでは不十分なコード ポイントがあります (すべての Unicode 文字の 16/17 だったと思います)。したがって、これは直接的な問題にはなりません。追加の 2 バイトStringを使用してこれらの ~1.048.576 文字の 1 つを格納したい場合、単に 2 つの配列位置が使用されるためです。String

これは、直接的な問題を引き起こすことなくString、常に追加の 2 バイトが存在する可能性があるため、s に対して機能します。ただし、UTF-16エンコーディングとは対照的に、 16ビットの固定長を持つ単一変数に関しては、これらの文字をどのように格納できますか、特にJavaは2バイトの「char」でどのようにそれを行うのですか?タイプ

4

2 に答える 2

26

答えはjavadocにあります:

charデータ型(したがって、Characterオブジェクトがカプセル化する値)は、文字を固定幅の16ビットエンティティとして定義した元のUnicode仕様に基づいています。その後、Unicode標準が変更され、16ビットを超える表現が必要な文字を使用できるようになりました。

有効なコードポイントの範囲は、Unicodeスカラー値として知られるU+0000からU+10FFFFになりました。(Unicode標準のU + n表記の定義を参照してください。)U+0000からU+FFFFまでの文字のセットは、Basic Multilingual Plane(BMP)と呼ばれることもあります。コードポイントがU+FFFFより大きい文字は、補助文字と呼ばれます。Java 2プラットフォームは、char配列とStringクラスおよびStringBufferクラスでUTF-16表現を使用します。この表現では、補足文字はchar値のペアとして表され、最初は高サロゲート範囲(\ uD800- \ uDBFF)から、2番目は低サロゲート範囲(\ uDC00- \ uDFFF)からです。

したがって、char値は、サロゲートコードポイントまたはUTF-16エンコーディングのコードユニットを含む、Basic Multilingual Plane(BMP)コードポイントを表します。int値は、補足コードポイントを含むすべてのUnicodeコードポイントを表します。intの下位(最下位)21ビットはUnicodeコードポイントを表すために使用され、上位(最上位)11ビットはゼロでなければなりません。

特に指定のない限り、補足文字および代理文字値に関する動作は次のとおりです。char値のみを受け入れるメソッドは、補足文字をサポートできません。サロゲート範囲のchar値を未定義の文字として扱います。たとえば、Character.isLetter('\ uD840')はfalseを返しますが、この特定の値の後に文字列内の低いサロゲート値が続く場合は、文字を表します。int値を受け入れるメソッドは、補助文字を含むすべてのUnicode文字をサポートします。たとえば、Character.isLetter(0x2F81A)は、コードポイント値が文字(CJKイデオグラフ)を表すため、trueを返します。Java SE APIのドキュメントでは、U+0000からU+10FFFFの範囲の文字値にUnicodeコードポイントが使用されています。Unicodeコード単位は、UTF-16エンコーディングのコード単位である16ビットのchar値に使用されます。Unicodeの用語の詳細については、Unicodeの用語集を参照してください。

簡単に言った:

  • charルールの16ビットは、Unicode標準の古いバージョン用に設計されました
  • 基本多言語面にないUnicodeルーン(コードポイント)を表すために、2つの文字が必要になる場合があります。特にBMP外のユニコードルーンを処理するためにcharを頻繁に使用しないため、この種の「機能」があります。

さらに簡単に言った:

  • java charはUnicodeコードポイントを表すわけではありません(常にではありません)。

余談ですが、UnicodeがBMPを超えて拡張されたため、UTF-16はグローバルに無関係になり、UTF-16では固定のバイト文字比さえ有効になりませんでした。そのため、より現代的な言語はUTF-8に基づいています。このマニフェストはそれを理解するのに役立ちます。

于 2012-10-28T20:00:57.800 に答える
8

基本的に、文字列はUTF-16コードユニットのシーケンスを格納します...これは、Unicodeコードポイントのシーケンスを格納することと同じではありません。

基本多言語面の外側の文字が必要な場合、それは内の2つのUTF-16コードユニットを占有しますString

ほとんどのString操作- length()、、などはcharAtsubstring()UTF-16コードユニットの数を処理します。ただし、codePointAt()完全なUnicodeコードポイントを処理するような操作があります...ただし、インデックスはUTF-16コード単位で表現されます。

編集:非BMPコードポイントを単一に格納したい場合charは、基本的に運が悪いです。256を超える個別の値をbyte変数に格納したいようなものです...それは機能しません。他の場所(たとえば)でコードポイントを表すための規則に従うと、変数Stringを使用するのが最善です。int

于 2012-10-28T20:01:17.160 に答える