全世界に広がるインターネットでは、世界中どこでも使えるソフトウェアが必要になります。つまり、ユーザーの国や言語を意識しないで開発でき、様々な国や地域に合わせてローカライズできるソフトウェアです。Javaプラットフォームでは、グローバル・アプリケーションを開発するための豊富なAPI群が提供されています。このような国際化のためのAPIは、Unicode標準に基づいており、テキスト、数値、日付、通貨、およびユーザー定義のオブジェクトを任意の国の慣習に合わせる機能を備えています。
このドキュメントでは、Java Platform Standard Editionの国際化に関するAPIと機能の概要を説明します。コーディング例と詳しい手順の説明については、Javaチュートリアルを参照してください。APIの詳細については、「Java Platform Standard EditionのAPI仕様」を参照してください。
詳細は、Javaの国際化のホーム・ページを参照してください。
Javaプログラミング言語はUnicode文字セットをベースにしており、いくつかのライブラリではUnicode標準が実装されています。Unicodeは、世界の主要な書記法すべてに加えて、基本的な学術記号をサポートしています。Unicode仕様では最初、各文字を16ビット固定長の実体として定義していましたが、その後、16ビットより長い表現を必要とする文字も取り扱えるようにUnicode標準が変更されました。有効なコード・ポイントの範囲は現在、U+0000 - U+10FFFFです。UTF-16標準により定義されるエンコーディングでは、すべてのUnicodeコード・ポイントを、1つまたは2つの16ビット単位を使用して表現できます。
Javaプログラミング言語の基本データ型charは、符号なしの16ビット整数なので、U+0000 - U+FFFFの範囲のUnicodeコード・ポイントや、UTF-16のコード単位を表現できます。Javaプラットフォームで文字シーケンスを表現する各種の型およびクラスは、UTF-16のシーケンスです。そのような型およびクラスとしては、char[]、java.lang.CharSequenceの実装(たとえばStringクラス)、java.text.CharacterIteratorの実装などがあります。ほとんどのJavaソース・コードは、7ビット文字エンコーディングのASCIIまたは8ビット文字エンコーディングのISO-8859-1で記述されますが、処理の前にUTF-16に変換されます。
Characterクラスは、charプリミティブ型のオブジェクト・ラッパーとしての役割を果たします。Characterクラスには、isLowerCase()やisDigit()など、文字のプロパティを判別するためのstaticメソッドも含まれています。J2SE 5.0からは、これらのメソッドは、char (U+0000 - U+FFFFの範囲のUnicodeコード・ポイントを表現できる)またはint (すべてのUnicodeコード・ポイントを表現できる)のいずれかを受け付けるようにオーバーロードされています。
Javaプラットフォームでは、ロケールは、言語と地域の特定の組み合わせに対する単なる識別子です。ロケール固有の属性の集合ではありません。ロケール固有の情報は、ロケールの影響を受けるクラスがそれぞれ独自に保持しています。このような設計のため、ロケール固有のリソースを保持する方法に関し、ユーザー・オブジェクトとシステム・オブジェクトで違いはありません。どちらも、標準のローカリゼーション・メカニズムを使います。
Javaプログラムには、単一のグローバル・ロケールは割り当てられていません。ロケールに依存するすべての操作には、引数として明示的にロケールを渡すことができます。これにより、多言語プログラムが非常に簡単になります。グローバル・ロケールが強制的に使われることはありませんが、ロケールを明示的に管理する必要のないプログラムでは、デフォルトのロケールを利用できます。デフォルト・ロケールを使うと、全体的な表示形式を一度の選択で変えることができます。
Javaのロケールは、別のオブジェクトから出される、ある動作に対する要求として機能します。たとえば、カレンダ・オブジェクトにフランス語系カナダ用ロケールを渡すと、ケベック州の慣習に従って正しく動作するようカレンダに要求したことになります。ロケールを受け取ったオブジェクトは、適切な処理を行わなければなりません。オブジェクトが特定のロケールに対してローカライズされていない場合、オブジェクトは、ローカライズされているロケールでよく似たものを探します。たとえば、カレンダ・オブジェクトがフランス語系カナダのロケール用にローカライズされていなくても、一般的なフランス語についてはローカライズされている場合は、代わりにフランス語のローカライズ版を使います。
Localeオブジェクトは、地理的、政治的、または文化的に特定の地域を表します。タスクを実行するためにロケールを必要とする操作のことを、ロケール依存操作と呼びます。ロケール依存操作は、Localeオブジェクトを使用して、ユーザーに合うように情報を加工します。たとえば、数値の表示はロケールに依存する操作です。数値の書式は、ユーザーに固有の国、地域、文化などの慣習や決まりに従って設定する必要があります。
Javaプラットフォームでは、クラスごとに独自のローカライズ版が保持されるので、サポートされるロケールの集合は1種類だけでなくてもかまいません。ただし、Javaプラットフォームのクラスとしては、一貫性のあるローカリゼーションをサポートしています。Javaプラットフォームのほかの実装では、異なるロケールをサポートする場合があります。JREがサポートするロケールの一覧は、サポートされているロケールに関するWebページを参照してください。
すべてのロケール依存クラスは、サポートするロケール用にカスタマイズされたリソースにアクセスできなければなりません。ローカリゼーションの処理を容易にするには、ロケールごとにリソースをグループ化し、プログラムのロケールに依存しない部分から切り離すことが有用です。
ResourceBundleクラスは、リソースのコンテナを表す抽象基底クラスです。プログラムでは、特定のロケールのためのリソースを含むResourceBundleのサブクラスを作成します。使用するコードを変更しなくても、ResourceBundleのインスタンスに新しいリソースを追加したり、ResourceBundleの新しいインスタンスをシステムに追加したりできます。リソースをクラスとしてパッケージ化することで、Javaのクラス・ローディング・メカニズムを利用してリソースを探すことができます。
リソース・バンドルには、ロケール固有のオブジェクトが含まれます。Stringオブジェクトなど、ロケール固有のリソースが必要な場合は、現在のユーザーのロケールに適したリソース・バンドルからリソースをロードします。このようにして、リソースのバンドルに含まれているロケール固有の情報のすべて、または少なくとも大部分を切離し、ユーザーのロケールとの依存関係が弱いコードを作成できます。
そのため、次のような特徴を備えたJavaコードを作成できます。
ResourceBundle.ControlはResourceBundleのネストされたクラスです。このクラスで、ResourceBundle.getBundleファクトリ・メソッドから呼び出されるメソッドを定義すれば、リソース・バンドル・ロード処理の動作を変更することができます。たとえば、XMLなどのアプリケーション固有のリソース・バンドル形式は、メソッドをオーバーライドすることでサポート可能になります。
ListResourceBundleは、リストを便利かつ容易に使用できる、ロケールに対するリソースを管理するResourceBundleのabstractサブクラスです。
PropertyResourceBundleクラスはResourceBundleの具象サブクラスで、プロパティ・ファイルから取り出した固定文字列群を利用して、ロケールのリソースを管理します。
java.util.Dateクラスは、タイムゾーンやロケールとは関係なく、時間の特定の瞬間をミリ秒の精度で表します。
Dateクラスには、日付を年、月、日、時、分、秒の値として解釈したり、日付の文字列の書式指定や構文解析を実行したりするメソッドがいくつか組み込まれています。これらのメソッドは国際化と互換性がないため、その大部分は使用が推奨されていません。これらのメソッドの代わりに、日付と時間のフィールド間の変換にはCalendarクラスを、また日付の文字列の書式指定と構文解析にはDateFormatクラスを、それぞれ使う必要があります。
Calendarクラスは抽象基底クラスで、内部時間(1970年1月1日00:00:00 GMTからの経過時間をミリ秒で表したもの)と、年、月、週などを表す整数値の間の変換を行うことができます。GregorianCalendarクラスはCalendarクラスを具体化したサブクラスで、グレゴリオ暦(太陽暦)の規則に従ってこの処理を行います。
Calendarクラスとそのサブクラスは、時間の値をさまざまな方法で操作するときに便利です。Calendarオブジェクトのフィールドと結果として得られた日付に対して、数値演算を行うことができます。Calendarオブジェクトでは、特定の言語とカレンダのスタイルに対する日付と時間の書式指定を実装するために必要なすべての時間フィールドの値を生成できます。詳細は、「サポートされるカレンダ」のWebページを参照してください。
抽象クラスであるTimeZoneは、GMT (グリニッジ標準時)のタイムゾーンのオフセットと使用可能なサマー・タイムのオフセットをカプセル化しています。TimeZone.getTimeZoneファクトリ・メソッドを呼び出せば、タイムゾーンIDに対応するTimeZoneインスタンスが得られます。TimeZone.getDefaultファクトリ・メソッドは、プラットフォームのタイムゾーンを自動的に検出し、そのプラットフォームに合ったTimeZoneインスタンスを返します。
Calendarクラスとそのサブクラスは、TimeZoneクラスを使用して現地時間とUTCとの変換を行います。UTCは、Dateオブジェクトが使用する内部表現です。ほとんどのプログラムでは、TimeZoneオブジェクトを直接扱う必要はありません。
データを出力するときの書式指定には、多くの文化的な慣習が適用されます。数値、日付、時間、およびメッセージのすべてについて、書式を指定してからでないと表示できない場合があります。Javaプラットフォームでは、柔軟性のある書式指定クラス群が提供されており、ロケールの標準的な書式および独自に定義された書式の両方を扱うことができます。これらの書式指定クラスを使うと、書式を設定された文字列の構文を解析して、構成するオブジェクトに戻すこともできます。
Formatクラスは、日付、時間、メッセージ、数値など、ロケールに依存する情報に書式を指定する機能のための、抽象基底クラスです。主要なサブクラスとして、DateFormat、NumberFormat、およびMessageFormatの3つが提供されています。これら3つのクラスでは、それぞれ独自のサブクラスが提供されています。
日付と時間は内部的にはロケールに依存しない方法で格納されますが、ロケールを反映した形式で表示できるよう書式を指定する必要があります。たとえば、次は同じ日付に対する異なる書式の例です。
DateFormatクラスは、ロケールに依存しない方法で日付と時間の値の書式指定と構文解析を行うための、抽象基底クラスです。特定のロケールに対する時間の標準書式を取得するためのstaticファクトリ・メソッドがいくつか用意されています。
DateFormatオブジェクトは、CalendarオブジェクトとTimeZoneオブジェクトを使って、時間の値を解釈します。デフォルトでは、特定のロケールに対するDateFormatオブジェクトは、そのロケールに対する適切なCalendarオブジェクトとシステムのデフォルトのTimeZoneオブジェクトを使います。これらの設定は、必要に応じてオーバーライドできます。
SimpleDateFormatクラスは具象クラスで、ロケールに依存した方法で日付と時間の書式指定と構文解析を行います。このクラスを使うと、書式指定(ミリ秒をテキストに)、構文解析(テキストをミリ秒に)、および正規化を行うことができます。
DateFormatSymbolsクラスは、月の名前、曜日の名前、時間、タイムゾーンのデータなど、日付と時間の書式指定に関するローカライズ可能なデータをカプセル化するために使います。DateFormatクラスとSimpleDateFormatクラスはどちらも、DateFormatSymbolsクラスを使ってこの情報をカプセル化します。
通常、プログラムでDateFormatSymbolsクラスを直接使うことはありません。実際には、DateFormatクラスのファクトリ・メソッドで、書式指定の機能を実装します。
NumberFormatクラスは、数値データの書式指定と構文解析のための抽象基底クラスです。異なる種類のロケール固有の数値書式を取得するため、staticファクトリ・メソッドがいくつか用意されています。
NumberFormatクラスは、任意のロケールで数値の書式指定と構文解析を行うときに役に立ちます。このクラスを使うコードは、小数点、桁区切り、使われている特定の10進数字、または数値の書式が10進数かどうかなどに対するロケールの規則から、完全に独立しています。通常の10進数、通貨、パーセントなどで数値を表示することもできます。
数値は、内部的にはロケールに依存しない方法で格納されていますが、ロケールを反映した形式で表示できるよう書式を指定する必要があります。たとえば、「#,###.00」というパターンを使うと、同じ数値でも次のように異なる書式になる場合があります。
DecimalFormatクラスは、NumberFormatクラスの具象サブクラスで、10進数値の書式指定を行うことができます。通常、このクラスのインスタンスを直接生成することはありませんが、提供されているファクトリ・メソッドは使います。
DecimalFormatクラスには、数値の書式設定の方法を指定するパターン文字列を受け取る機能があります。パターンでは、数値の精度、先頭の0を表示するかどうか、使用する通貨記号などの属性を指定します。プログラムで独自の書式を作る必要がある場合は、パターン文字列を変更できます。
DecimalFormatSymbolsクラスは、数値の書式を指定するときにDecimalFormatが必要とする記号群(小数点、グループ化区切り文字など)を表します。DecimalFormatクラスは、それ自体のために、ロケール・データからDecimalFormatSymbolsクラスのインスタンスを生成します。これらの記号のいずれかを変更する必要がある場合は、DecimalFormatオブジェクトからDecimalFormatSymbolsオブジェクトを取得して修正できます。
ChoiceFormatクラスは、NumberFormatクラスの具象サブクラスです。ChoiceFormatクラスを使うと、ある範囲の数値に書式を設定できます。このクラスは、通常、MessageFormatオブジェクトの中で複数形を処理するときに使われます。詳細は、次の「MessageFormatクラス」を参照してください。
プログラムでは、一連の文字列、数値、およびほかのデータからメッセージを作らなければならない場合がよくあります。たとえば、ディスク・ドライブにあるファイルの数を表示するメッセージのテキストは、状況によって次のように変わります。
一連の文字列と数値から組み立てるメッセージがハードコードされている場合は、ほかの言語に翻訳できません。たとえば、次の例で、パラメータの「3」と「G」の位置が違うことに注意してください。
MessageFormatクラスを使うと、言語に依存しない方法で、文字や数字を連結したメッセージを作成できます。MessageFormatオブジェクトは、複数のオブジェクトを受け取り、書式を設定して、パターンの適切な位置に書式を設定した文字列を挿入します。
ParsePositionクラスは、Formatクラスとそのサブクラスによって使用され、構文解析を行なっている間の現在位置を記録します。FormatクラスのparseObject()メソッドでは、引数としてParsePositionオブジェクトが必要です。
FieldPositionクラスは、Formatクラスとそのサブクラスによって使用され、書式指定された出力のフィールドを識別します。Formatクラスのformat()メソッドの1つでは、引数としてFieldPositionオブジェクトが必要です。
プログラムでは、文字列の操作が頻繁に必要になります。文字列に対する共通の操作として、検索とソートがあります。文字列の照合やテキストのさまざまな境界の検出など、ある種の処理は、正確に行おうとすると非常に難しく、複数の言語を考慮する必要がある場合はさらに困難になります。Javaプラットフォームでは、このような共通の文字列操作の多くをロケールに依存した方法で処理するためのクラス群が提供されています。
Collatorクラスでは、ロケールに依存した文字列の比較が行われます。自然言語テキストのための検索ルーチンおよびアルファベット順ソート・ルーチンを作るには、このクラスを使います。Collatorは、抽象基底クラスです。サブクラスでは、具体的な照合方法が実装されます。現在では、1つのサブクラスRuleBasedCollatorがJavaプラットフォームで提供されており、広範囲の言語に適用可能です。さらに特殊な必要性がある場合には、ほかのサブクラスを作成できます。
RuleBasedCollatorクラスは、Collatorクラスの具象サブクラスで、データ駆動の簡単な表照合機能を提供します。RuleBasedCollatorクラスを利用し、目的に合わせてカスタマイズした表ベースの照合機能を作成できます。たとえば、大文字、アクセント、およびUnicode複合文字を無視(または意識)する照合機能を作ることができます。
CollationElementIteratorクラスは、多国語文字列の各文字を処理するときのイテレータとして使われます。イテレータは、位置付けされた文字の順序の優先順位を返すために使われます。文字の順序の優先順位つまりキーは、特定のCollatorオブジェクトの中で文字を照合する方法を定義するものです。CollationElementIteratorクラスは、RuleBasedCollatorクラスのcompare()メソッドで使われます。
CollationKeyオブジェクトは、特定のCollatorオブジェクトの規則が適用された文字列を表します。2つのCollationKeyオブジェクトを比較すると、それらが表す文字列の相対的な順序が返されます。CollationKeyオブジェクトを使って文字列を比較する方が、一般に、Collator.compare()メソッドを使うより高速です。したがって、文字列の一覧をソートするときのように、文字列を比較する回数が多い場合は、CollationKeyオブジェクトを使う方が効率的です。
BreakIteratorクラスは、テキスト文字列の中から次のような種類の境界の位置を見つけるためのメソッドを間接的に実装します。
行、文、語、および文字を区切る場所の規則は、言語の種類により異なります。BreakIteratorクラスはロケールに依存するので、テキストを操作するプログラムで使うことができます。たとえば、文字の強調表示、語の切り取り、次の文へのカーソルの移動、行末での折り返しなどが可能なワープロ・プログラムを考えます。このワープロ・プログラムは、分割イテレータを使ってテキストの論理的な境界を決定し、ロケールを意識した方法でテキストを操作できるようにします。
StringCharacterIteratorクラスは、Unicode文字の文字列に対して双方向の反復処理を行う機能を提供します。このクラスは、カーソルを使ってある範囲のテキストの中を移動し、個別の文字または文字のインデックス値を返すことができます。StringCharacterIteratorクラスは、CharacterIteratorインタフェースの文字イテレータ機能を実装しています。
CharacterIteratorインタフェースは、Unicode文字に対する双方向の反復処理のためのプロトコルを定義しています。ある範囲のテキストの中を移動し、個別のUnicode文字またはそのインデックス値を返すクラスの場合、このインタフェースを実装する必要があります。CharacterIteratorは、文字検索を行うときに役に立ちます。
Normalizerクラスは、Unicodeテキストを等価の形式に変換あるいは復元するメソッドを提供します。このクラスは、Unicode標準によって定義されたUnicode Normalization Formをサポートします。
java.textおよびjava.utilパッケージ内のクラスが提供する、ロケールに依存するサービスは、ロケールに依存するサービスのSPIを実装すれば、Javaランタイムがまだサポートしていないロケールにも拡張することができます。java.utilパッケージに含まれるCurrency、Locale、TimeZoneの各クラスのローカライズされた記号や名前のほか、java.textパッケージに含まれる次のクラスの実装は、SPIとともにプラグインすることができます。
Javaプラットフォームは、ネイティブの文字エンコーディングとしてUnicodeを使っていますが、Javaプログラムの多くでは、まだ、ほかのエンコーディングのテキスト・データを扱う必要があります。そのため、Javaでは、多くの標準的な文字エンコーディングとUnicodeの間の変換を行うクラス群が提供されています。Unicode以外のテキスト・データを扱う必要があるJavaプログラムでは、データをいったんUnicodeに変換し、Unicodeとしてデータを処理してから、その結果を変換して外部の文字エンコーディングに戻します。InputStreamReaderクラスとOutputStreamWriterクラスでは、ほかの文字エンコーディングとUnicodeの間の変換を行うメソッドが提供されています。
サポートされているエンコーディングInputStreamReader、OutputStreamWriter、Stringの各クラスでは、Unicodeと「サポートされているエンコーディング」の一覧に示されている文字エンコーディングの間での変換が可能です。
Javaプラットフォームでは、文字データ処理機能を向上させるため、java.ioパッケージに機能が追加されています。つまり、ReaderクラスとWriterクラスの追加、およびPrintStreamクラスに対する拡張です。
ReaderクラスとWriterクラスの階層は、文字ストリームで入出力操作を行う機能を提供します。これらの階層は、InputStreamクラスとOutputStreamクラスの階層と並列になっていますが、バイトのストリームではなく、文字のストリームを処理します。文字ストリームを使うと、特定の文字エンコーディングに依存しないプログラムを簡単に記述でき、したがって、国際化も簡単になります。ReaderクラスとWriterクラスには、Unicodeとほかの文字エンコーディングの間の変換を行う機能もあります。ReaderクラスとWriterクラスの階層の詳細については、「文字ストリーム」を参照してください。
PrintStreamクラスは、システムのデフォルトの文字エンコーディングと行末記号を使って出力を生成します。この変更により、System.out.println()などのメソッドは、ASCII以外のデータをより適切に処理できます。
java.nio.charsetパッケージは、文字エンコーディング変換のための土台を提供します。アプリケーションでは、このパッケージに含まれるクラスを使用して、組込みの文字変換プログラムの動作を微調整できます。また、java.nio.charset.spiパッケージを使用すると、組込みの文字変換プログラムでサポートされていない文字エンコーディング用のカスタム変換プログラムを作成することもできます。
インプット・メソッドは、ユーザーがテキストを単にキーボード上でタイプする以外の方法でテキストを入力できるソフトウェア・コンポーネントです。数千種類もの文字を使う日本語、中国語、韓国語を、キーボードのそれよりはるかに少ないキーで入力する場合に、共通してこのインプット・メソッドを使用します。Javaプラットフォームでは、この3言語以外のインプット・メソッドもサポートされており、手書きや音声認識などの異なる入力メカニズムにも使用できます。
また、Javaプラットフォームでは、WindowsまたはSolarisなどのホスト・オペレーティング・システムから提供されるネイティブ・インプット・メソッドを使うことができるほか、Javaプログラミング言語で記述されたインプット・メソッドを実装して使うこともできます。
インプット・メソッドという用語は、Javaプログラミング言語のクラス・メソッドを指しているのではありません。
Swingテキスト・コンポーネントは、インプット・メソッドを使用したテキスト入力のための統合ユーザー・インタフェースを提供します。ロケールに応じて、オンザスポットまたはビロウザスポット入力方式が使用されます。ほとんどのロケールで使用されているオンザスポット(インライン)入力方式の場合、インプット・メソッドはテキストを入力している間テキストをテキスト・コンポーネントに直接挿入します。中国語圏のロケールで使用されているビロウザスポット入力方式の場合は、独立した変換ウィンドウが使用されます。このウィンドウは、確定したテキストの挿入位置の近くに自動的に配置されます。
Swingテキスト・コンポーネントを使用するアプリケーションでは、テキスト・コンポーネントとインプット・メソッド間のやり取りを調整する必要はありません。ただし、ドキュメントを保存または印刷する場合など、すべてのテキストの確定が必要な場合は、InputContext.endCompositionを呼び出す必要があります。
Input Method Frameworkは、テキスト編集時に、テキスト編集コンポーネントとインプット・メソッドの間の共同作業を可能にします。このフレームワークを使用するのは、テキスト編集コンポーネントまたはインプット・メソッドを開発するプログラマです。その他のアプリケーション開発者は、通常はほとんど使用しません。たとえば、ドキュメントを保存または印刷する場合など、すべてのテキストの確定が必要な場合は、InputContext.endCompositionを呼び出す必要があります。
「Input Method Framework」のページから、仕様およびAPIドキュメントへのリンクを利用できます。