モジュール java.base
パッケージ java.text

クラスMessageFormat

java.lang.Object
java.text.Format
java.text.MessageFormat
すべての実装されたインタフェース:
Serializable, Cloneable

public class MessageFormat extends Format
MessageFormatは、連結されたメッセージを、言語に依存しない方法で構築するためのものです。 エンド・ユーザー用に表示するメッセージは、この方法で構築してください。

MessageFormatは、1組のオブジェクトをフォーマットし、フォーマットした文字列をパターンの適切な場所に挿入します。

ノート: MessageFormatがほかのFormatクラスと異なる点は、MessageFormatオブジェクトを(getInstanceスタイルのファクトリ・メソッドではなく)そのコンストラクタの1つで作成するということです。 MessageFormatでは、ロケール固有の動作は実装されていないので、ファクトリ・メソッドは必要ありません。 ロケール固有の動作は、提供するパターンおよび挿入された引数に使用するサブフォーマットによって定義されます。

パターンとその解釈

MessageFormatは次のパターンを使用します。
 MessageFormatPattern:
         String
         MessageFormatPattern FormatElement String

 FormatElement:
         { ArgumentIndex }
         { ArgumentIndex , FormatType }
         { ArgumentIndex , FormatType , FormatStyle }

 FormatType: one of 
         number date time choice

 FormatStyle:
         short
         medium
         long
         full
         integer
         currency
         percent
         SubformatPattern
 

String内で1組の単一引用符を使用して、単一引用符を除く任意の文字を囲むことができます。 たとえば、パターン文字列"'{0}'"は、FormatElementではなく、文字列"{0}"を表します。 単一引用符自体を表すには、String全体で単一引用符を2つにする('')必要があります。 たとえば、パターン文字列"'{''}'"は、'{''}' (左右の中括弧が引用符で囲まれたもの) ではなく'{ (引用の開始と左中括弧)、'' (単一引用符)、}' (右中括弧と引用の終了)が連続するものとして解釈され、文字列"{}" ではなく"{'}"を表します。

SubformatPatternは対応するサブフォーマットで解釈され、サブフォーマットに依存するパターンのルールが適用されます。 たとえば、パターン文字列"{1,number,$'#',##}" (下線付きのSubformatPattern)と指定すると、ハッシュ記号(#)が付いた数値フォーマットが生成されます。結果は、 "$#31,45"のようになります。 詳細は、Formatサブクラスのドキュメントを参照してください。

一致しない引用符は、指定されたパターンの最後で閉じられるものとして処理されます。 たとえば、パターン文字列"'{0}"はパターン"'{0}'"として処理されます。

引用符で囲まれていないパターン内の中括弧のバランスを取る必要があります。 たとえば、"ab {0} de""ab '}' de"は有効なパターンですが、"ab {0'}' de""ab } de""''{''"は無効です。

警告:
メッセージ・フォーマット・パターン内での引用符の使用ルールは、あまり明快ではありません。 特に、単一引用符を二重にする必要の有無がローカライザにとっては明らかでないこともあります。 ローカライザにルールについて情報を提供し、リソースにバンドルされるソース・ファイル内のコメントなどによって、どの文字列がMessageFormatで処理されるのかを示すようにしてください。 ローカライザは、変換した文字列でオリジナルのバージョンにはない単一引用符を使用しなければならない場合があります。

ArgumentIndex値は、数字'0' - '9'を使用して記述した0以上の整数です。formatメソッドに渡されたarguments配列またはparseメソッドによって返された結果の配列のインデックスを表します。

FormatTypeおよびFormatStyle値は、フォーマット要素のFormatインスタンスの生成に使用します。 次の表に、Formatインスタンスへの値のマップについて示します。 表にない組み合わせは使用できません。 SubformatPatternは、使用するFormatサブクラスに対して有効なパターン文字列である必要があります。

FormatTypeおよびFormatStyleの値をFormatインスタンスにマップする方法を示します
FormatType FormatStyle 生成されるサブフォーマット
(なし) (なし) null
number (なし) NumberFormat.getInstance(getLocale())
integer NumberFormat.getIntegerInstance(getLocale())
currency NumberFormat.getCurrencyInstance(getLocale())
percent NumberFormat.getPercentInstance(getLocale())
SubformatPattern new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale()))
date (なし) DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getDateInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getDateInstance(DateFormat.LONG, getLocale())
full DateFormat.getDateInstance(DateFormat.FULL, getLocale())
SubformatPattern new SimpleDateFormat(subformatPattern, getLocale())
time (なし) DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getTimeInstance(DateFormat.LONG, getLocale())
full DateFormat.getTimeInstance(DateFormat.FULL, getLocale())
SubformatPattern new SimpleDateFormat(subformatPattern, getLocale())
choice SubformatPattern new ChoiceFormat(subformatPattern)

使用方法

次にいくつかの使用例を示します。 もちろん実際の国際化されたプログラムでは、メッセージ・フォーマット・パターンやその他の静的な文字列はリソース・バンドルから取得されます。 その他のパラメータは実行時に動的に決定されます。

最初の例では、staticメソッドMessageFormat.formatを使用しています。このメソッドは内部的に、1度限りの使用目的でMessageFormatインスタンスを作成します。

int planet = 7;
String event = "a disturbance in the Force";

String result = MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
    planet, new Date(), event);
出力は次のとおりです。
 At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7.
 

次の例では、繰返し使用可能なMessageFormatインスタンスを作成しています。

int fileCount = 1273;
String diskName = "MyDisk";
Object[] testArgs = {Long.valueOf(fileCount), diskName};

MessageFormat form = new MessageFormat(
    "The disk \"{1}\" contains {0} file(s).");

System.out.println(form.format(testArgs));
fileCountにさまざまな値を設定した場合の出力結果を次に示します。
 The disk "MyDisk" contains 0 file(s).
 The disk "MyDisk" contains 1 file(s).
 The disk "MyDisk" contains 1,273 file(s).
 

より高度なパターンを実現したければ、ChoiceFormatを使用することで、単数と複数に対してそれぞれ適切な形式を生成できます。

MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
double[] filelimits = {0,1,2};
String[] filepart = {"no files","one file","{0,number} files"};
ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
form.setFormatByArgumentIndex(0, fileform);

int fileCount = 1273;
String diskName = "MyDisk";
Object[] testArgs = {Long.valueOf(fileCount), diskName};

System.out.println(form.format(testArgs));
fileCountにさまざまな値を設定した場合の出力結果を次に示します。
 The disk "MyDisk" contains no files.
 The disk "MyDisk" contains one file.
 The disk "MyDisk" contains 1,273 files.
 

上の例のようにChoiceFormatをプログラム的に作成できますが、次のようにパターンを使用することもできます。 詳細は、ChoiceFormatを参照してください。

form.applyPattern(
   "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");

ノート: 上記からわかるように、MessageFormatChoiceFormatによって生成される文字列の扱いはかなり特殊です。「{」の存在によってサブフォーマットであることを示し、再帰処理を行っています。 MessageFormatChoiceFormatを両方とも(文字列パターンとしてではなく)プログラム的に作成する場合には、再帰的に繰り返すフォーマットを作成して永久ループに陥らないように注意してください。

1つの引数が文字列内で複数回解析されると、最後に一致するものが解析の最終結果になります。 たとえば、

MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
Object[] objs = {Double.valueOf(3.1415)};
String result = mf.format( objs );
// result now equals "3.14, 3.1"
objs = mf.parse(result, new ParsePosition(0));
// objs now equals {Double.valueOf(3.1)}

同様に、同じ引数が複数回出てくるパターンを使ってMessageFormatオブジェクトを解析すると、最後に一致するものが返されます。 たとえば、

MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
String forParsing = "x, y, z";
Object[] objs = mf.parse(forParsing, new ParsePosition(0));
// objs now equals {new String("z")}

Synchronization

メッセージ・フォーマットは同期化されません。 スレッドごとに別のフォーマット・インスタンスを作成することをお薦めします。 複数のスレッドがフォーマットに並行してアクセスする場合は、外部的に同期化する必要があります。

導入されたバージョン:
1.1
関連項目: