javaのMessageFormatの使い方のまとめ(0埋め(パディング)、日付、メッセージ置換等)

Javaで文字列の一部を置換する場合には、replaceや正規表現での置換を用いたりしますが、エラーメッセージなど、定型の文字列の一部を渡したパラメータで置き換える形で生成するには、MessageFormatクラスを使うと便利です。

特に、置き換える元の文字列は、

「エラーコード:{0} エラー理由:{1}


のように設定しておけるので、プロパティ・ファイルなど、プログラムの外部に保持して、比較的自由に変更することができます。

MessageFormatで文字列をフォーマット(置換)する2つの方法と使い分け

MessageFormatは2つの使い方があります。

staticなメソッドを使う方法とインスタンスを生成して同じテンプレートを使いまわす方法です。

staticなメソッドを使う方法

staticなメソッドを使う方法では、format()が呼ばれたときに、内部的には一回限りの目的のために MessageFormat インスタンスを生成しています。

String template = "Hello! {0}さん。{1}も元気?";
Object[] params = {"太郎","花子"};
String message = MessageFormat.format(template, params);
System.out.println(message);

インスタンスを生成する方法(パフォーマンス良し)

一方、インスタンスを生成する方は、その生成時にテンプレートの文字列を引数に取りますので、そのテンプレートに対して、異なるパラメータを渡すことができます。

そのため、繰り返す際のパフォーマンスには優れていますね。

MessageFormat mf = new MessageFormat("エラーコード:{0} エラー理由:{1}");
String[] params2 = {"E-112", "不正な文字列です。"};
String[] params3 = {"E-113", "文字列が空です。"};
String[] params4 = {"E-114", "セッションが不正です。"};
System.out.println(mf.format(params2));
System.out.println(mf.format(params3));
System.out.println(mf.format(params4));

ちょっとしたフォーマットのTips

MessageFormatは、その名の通り、メッセージ出力のためにフォーマットを指定して表示できるクラスで、文字列だけがそのフォーマット対象ではありません。数字や日付もフォーマット指定して出力できます。

数字のフォーマット

数字も出力可能ですが、デフォルトのフォーマット指定だと、数字が千桁以上になるとカンマがついて出力されます。これを、カンマ無しで表示するには、以下のように「#」を指定しましょう。

MessageFormat mfNo = new MessageFormat("数字そのまま{0} or カンマなし:{1,number,#}");
Integer[] paramsNo = {123456,123456};
System.out.println(mfNo.format(paramsNo));

数字を0埋め(パディング)

上記の数字フォーマットを応用すると、数字の左側を0埋めして「00001」のように出力することもできます。

MessageFormat mfNo2 = new MessageFormat("0埋め数字{0,number,0000}");
Integer[] paramsNo2 = {1};
System.out.println(mfNo2.format(paramsNo2));

同じことを別のクラス(String.format)でやるとしたら、

String str = String.format("%05d", 1);
System.out.println(str);

のようにも書くことができます。

日付と時間の変換

よくファイルのネーミングやログの出力時の参考に「YYYYMMDD」の形式の文字列が欲しくなることがありますが、そんなこともできます。

MessageFormat mfDay = new MessageFormat("こんにちは。今日は{0,date,yyyy年MM月dd日}、時刻は{0,time}です。数字だけにすると、{0,date,yyyyMMdd}、時刻は{0,time,HHMMSS}です。");
Object[] paramsDay = {new Date(System.currentTimeMillis())};
System.out.println(mfDay.format(paramsDay));

同じことをSimpleDateFormatでやるとしたら

Date date = new Date();
String dateStr = new SimpleDateFormat("yyyyMMddhhmmss").format(date);
System.out.println(dateStr);

のようにも書けますね。

{0,date,yyyy年MM月dd日}のようにフォーマット形式を指定していますが、0(添え字)の次のひとつめ(date)はフォーマット・タイプ、2つ目(yyyy年MM月dd日)はフォーマット・スタイル(サブフォーマット・パターン)と言って、フォーマットのより詳しい形式を指定しています。

全部使ったMessageFormatのサンプルソース

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
 
public class Sample1 {
 
 
    public static void main(String[] args) {
 
        //staticなメソッドを使う方法
        String template = "Hello! {0}さん。{1}も元気?";
        Object[] params = {"太郎","花子"};
        String message = MessageFormat.format(template, params);
        System.out.println(message);
 
 
        //インスタンスを生成する方法
        MessageFormat mf = new MessageFormat("エラーコード:{0} エラー理由:{1}");
        String[] params2 = {"E-112", "不正な文字列です。"};
        String[] params3 = {"E-113", "文字列が空です。"};
        String[] params4 = {"E-114", "セッションが不正です。"};
        System.out.println(mf.format(params2));
        System.out.println(mf.format(params3));
        System.out.println(mf.format(params4));
 
 
        //数字のフォーマット
        MessageFormat mfNo = new MessageFormat("数字そのまま{0} or カンマなし:{1,number,#}");
        Integer[] paramsNo = {123456,123456};
        System.out.println(mfNo.format(paramsNo));
 
        String str = String.format("%05d", 1);
        System.out.println(str);
 
 
        //0埋め(パディング)
        MessageFormat mfNo2 = new MessageFormat("0埋め数字{0,number,0000}");
        Integer[] paramsNo2 = {1};
        System.out.println(mfNo2.format(paramsNo2));
 
 
        //日付と時間の変換
        MessageFormat mfDay = new MessageFormat("こんにちは。今日は{0,date,yyyy年MM月dd日}、時刻は{0,time}です。数字だけにすると、{0,date,yyyyMMdd}、時刻は{0,time,HHMMSS}です。");
        Object[] paramsDay = {new Date(System.currentTimeMillis())};
        System.out.println(mfDay.format(paramsDay));
 
        Date date = new Date();
        String dateStr = new SimpleDateFormat("yyyyMMddhhmmss").format(date);
        System.out.println(dateStr);
    }
 
}