charデータ型の使用上の注意
Javaでは文字を表すためにcharデータ型が使用されますが、char型はすべての文字を表すことはできません。
Unicode 文字セット
まず第一に、Java では Unicode 文字セットを使用していることを知っておく必要があります。登場する前は、ANSI、GB2312 など多くの文字セットがありました。異なる標準を持つ多くの文字セットがあるため、これは次の 2 つの問題につながります。
特定のコード値に対して、異なる文字が異なる文字セットの異なる文字に対応する可能性があります。
大きな文字セットを使用すると、言語が異なる可能性があります。一般的な文字の場合はシングルバイト エンコード、その他の文字の場合はマルチバイト エンコードなど、エンコード長が異なります。
Unicode 文字セットの登場は、エンコーディングを統一し、上記の問題を解消することを目的としています。いわゆる文字セットは、多くの異なる文字で構成されるコレクションです。 Unicode 文字セットは、文字自体を識別するために各文字に一意のコード ポイントを割り当てます。いわゆるコード ポイントは、U+ 接頭辞が追加された 16 進整数です。たとえば、文字 A のコード ポイントは U+0041 です。
Unicode 文字セットでは、これらの文字を送信および保存する方法を考慮する必要があります。これが、Unicode Transformation Format (UTF) と呼ばれる Unicode エンコードの実装方法です。よく知られている UTF-8、UTF-16 などは、異なる Unicode エンコーディングの実装方法です。
Unicode 文字セットの誕生当初、Unicode 文字セットのエンコードには固定長エンコード方式 UCS-2 (2 バイト ユニバーサル文字セット) が使用されていました。この方式では文字の長さが 16 ビットとして使用されます。エンコードなので、最大 2^16 = 65536 文字をエンコードできます (エンコード範囲は U+0000 ~ U+FFFF)。この状況下で、設計者はすべての文字をエンコードするために使用した数の半分未満を使用し、残りのスペースは将来の新しい文字をエンコードするのに十分であると考えました。
残念ながら、中国語、日本語、韓国語、その他の表意文字が継続的に追加されたため、Unicode 文字セットの文字数が 16 ビットでエンコードできる最大文字数をすぐに超えたため、設計者は Unicode に変更を加えました。新しいデザインのキャラクターセット。
新しいデザインでは、文字セット内のすべての文字が 17 のコード プレーンに分割されます。このうち、コードポイント範囲 U+0000 ~ U+FFFF を Basic Multilingual Plane (略称 BMP) とし、残りの文字を 16 個の補助プレーン (Supplementary Plane) に分割します。 U+10FFFF、補助面内のこれらの文字は補助文字と呼ばれます。
Unicode 文字セットの文字が異なるプレーンに再分類された後は、次の 2 つの側面に注意する必要があります:
BMP 範囲の文字は、基本的に UCS-2 の文字エンコーディングと同じです。ただし、BMP の U+ D800 ~ U+DFFF 部分は空白のままで、どの文字にも割り当てられません。補助プレーンの文字をエンコードするために使用されます。
各プレーンのすべての位置が指定されたキャラクターに割り当てられるわけではありません。その理由は次のとおりです。
BMP の U+D800 ~ U+DFFF 部分など、
予約済み。スペース
文字が足りません
UTF-16
UTF-16もUnicode文字を表すために16ビットエンコーディングを使用します。つまり、UTF-16のコード単位(コード単位)は16ビットです。コード単位は、文字エンコーディングの最も基本的な単位を指します。つまり、どの文字も n (n≥1) 個のコード単位で構成されている必要があります。
UTF-16 では、16 ビット長で 65536 文字しか表現できないため、BMP 範囲内のすべての文字がデフォルトでマッピングされるため、U+D800 ~ U+DFFF 部分は空白のままにし、補助プレーン文字も使用できます。この空白部分を利用して表現します。これは、スペースを無駄にすることなくすべての文字のエンコーディングの問題を解決する UTF-16 設計の工夫です。
それでは、補助平面の文字をどのように表現するのでしょうか?実際、補助プレーン文字のコード ポイントは、サロゲート ペアと呼ばれる 16 ビット長のコード単位のペアにエンコードされ、サロゲート ペアは BMP の U+D800 ~ U+DFFF 部分に収まる必要があります。これにより、Unicode 文字セット全体を 16 ビット コード単位でエンコードするという問題が解決されます。なお、U+D800~U+DFFFの部分をエージェント領域と呼ぶことができ、このうちU+D800~U+DBFFの部分を上位エージェント領域(先頭エージェント領域)と呼び、Uの部分をエージェント領域と呼ぶことができる。 +DC00 ~ U+DFFF 下位エージェント領域(リアエージェント領域)といいます。
以下では、補助プレーンの文字である U+64321 を UTF-16 でエンコードする例を通して、補助プレーン文字のエンコード方法を説明します。
まず、この文字のコードポイントから 0x10000 を減算して、20 ビットの長さの値を取得します。この値の範囲は 0x0000 ~ 0xFFFF の範囲内である必要があります。
Vxの上位10ビットの値を上位エージェントの演算基底Vhとし、下位10ビットの値を下位エージェントの演算基底Vlとして使用エージェント。これら 2 つの 10 ビット値の値の範囲は 0x0000 ~ 0x3FF である必要があります。
上位サロゲート領域と下位サロゲート領域の開始位置のコードポイントをそれぞれ使用して、Vh と Vl に対してビット単位の OR 演算を実行します。その結果は、文字 U+ の UTF-16 エンコードになります。補助平面の 64321。
したがって、最終的に、文字 U+64321 は、上位サロゲートと下位サロゲートで構成されるサロゲート ペアにエンコードされます。この文字を表すには、0xD950 と 0xDF21 を同時に使用する必要があります。
上記の例を通して、補助プレーン内の文字は、UTF-16 で 2 つの 16 ビット サロゲート コードで構成されるサロゲート ペアとしてエンコードされることがわかります。この文字をプログラムで表現する場合、それは必要ありません。 16 ビットのスペースを占有しますが、32 ビットのスペースを占有します。
Java プログラムで char データ型を使用することはお勧めできません
Unicode 文字セットと UTF-16 についての上記の説明の後で、Java で char データ型を使用することが推奨されない理由について説明します。プログラム。
Java は 16 ビット Unicode 文字セット、つまり UTF-16 を使用するため、Java の char データ型は固定長であり、その長さは常に 16 ビットのみです。char データ型は、次のコードポイントのみを表現できます。 U+ 0000 ~ U+FFFF の文字、つまり BMP 内の文字。コード ポイントがこの範囲を超える場合、補助文字が使用されている場合でも、char データ型はサポートされません。これは、補助文字の保存には 32 ビットの長さが必要であり、この文字の保存には String のみを使用できるためです。
上記で書かれたコードは、補助プレーンの文字を保存するために char データ型を使用しており、コンパイラは無効な文字定数のエラーを報告します。
インターネット ユーザーの継続的な増加とインターネット言語の継続的な充実に伴い、ユーザーはインターネット上で豊かな意味を表現するためにいくつかの特殊文字を使用することが増えており、これらの文字は補助面の補助文字となる可能性が高くなります。処理に char 型を使用すると、プログラムの堅牢性が低下する可能性があります。
文字列の詳細
文字列の長さを取得する
文字列はプログラミングでよく使用されるデータ型であり、文字列を表すために使用されます。 String のソース コードを見ると、基礎となる層が実際に char 型の配列を使用して文字を格納していることがわかります。
また、 length() メソッドを呼び出すと、文字列の長さ、つまり文字列内の文字数を取得できることもわかっています。その実装は、基になる値の配列の長さを直接返すことです。コードは次のとおりです。
上記の文字エンコーディングの知識と組み合わせると、Java の char の長さは常に 16 ビットであることがわかります。文字列内で補助文字を使用する場合、String の最下層には 2 つの char 型の長さが必要になります。文字を格納する配列値の場合、配列要素の位置が 2 つ必要です。したがって、次のプログラムでは予期しない結果が得られます:
私たちの考えによれば、文字列 tt には 8 文字しか含まれないはずですが、実際の出力は 9 文字です。 Java が 16 ビット Unicode 文字セットを使用することはすでに上で述べたので、Java のコード単位の長さも 16 ビットです。補助文字を表すには 2 つのコード単位が必要なので、文字列内の tt 文字は