答えは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に基づいています。このマニフェストはそれを理解するのに役立ちます。