【Java】 MessageFormat ( vs String.format() )

■ はじめに

http://blogs.yahoo.co.jp/dk521123/13687446.html
にある String.format() は、物凄く活用できるメソッドであるが
以下のような問題点があり、その代わりになるのが MessageFormat である

String.format() の問題点

 * 「%」単体で使えない
 → 「%%」でないと使えない。 
   replace()で事前に「%」→「%%」に変換したいところだが、
   そうすると、「%s」等も「%%s」になってしまい、使用できなくなる

■ MessageFormat

 * プレースホルダは、{0}、{1}、・・・となる。
 → C# の String.Format() と同じ。

API仕様

http://docs.oracle.com/javase/jp/6/api/java/text/MessageFormat.html

■ 使用上の注意

[1] 数字が千桁以上になると、デフォルトだとカンマがつく
[2] 「'」を使用したい場合、「''」とする
[3] カンマ排除対応やゼロ埋め時などで、空白を入れない
[4]「{」 or 「}」 を使用したい場合は、シングルクオーテーションマーク(')で囲む

[1] 数字が千桁以上になると、デフォルトだとカンマがつく

 * 以下で対応
  a) 「{0,number,#}」で指定 
  b) 事前に文字列変換しておく
  ~~~~~~~~~~~~~~
    System.out.println(MessageFormat.format("{0}", 100000)); # 100,000
    System.out.println(MessageFormat.format("{0,number,#}", 100000)); # 100000
  ~~~~~~~~~~~~~~

[2] 「'」を使用したい場合、「''」とする

    System.out.println(MessageFormat.format("''{0}''、{0}", "Test101"));

[3] カンマ排除対応やゼロ埋め時などで、空白を入れない

 * [1]のカンマ排除対応やゼロ埋め時などで、
   例えば、"{0, number,  0000}"のように空白があると、
   「【空白】00020」のように出力結果にも空白が反映されるので注意
  ~~~~~~~~~~~~~~
    System.out.println(MessageFormat.format("{0,number,0000}/{0, number, 0000}", 27)); # 0027/<SP>0027
  ~~~~~~~~~~~~~~

[4]「{」 or 「}」 を使用したい場合は、シングルクオーテーションマーク(')で囲む

    System.out.println(MessageFormat.format("'{'0'}'、{0}", "Test101"));
http://ymotoba.blogspot.jp/2008/06/blog-post_165.html

■ サンプル

import java.text.MessageFormat;
import java.util.Calendar;

public class Demo {
  public static void main(String[] args) {
    System.out.println(MessageFormat.format("{0}、{1}、{2}、{3}、{4}", "Test001",
        "Test002", 1000, String.valueOf(1000), "100.0%"));
    System.out
        .println(MessageFormat.format("{0}、{0}、{1}", "Test101", "Test102"));
    System.out.println(MessageFormat.format("'{'0'}'、'{'2, 3'}'、''{0}''、{1}",
        "Test101", "Test102"));

    System.out
        .println(MessageFormat.format("{0,number,#}/{0, number, #}", 100000));
    System.out
        .println(MessageFormat.format("{0,number,0000}/{0, number, 0000}", 27));
    System.out.println(MessageFormat.format("{0,date} {0,time}",
        Calendar.getInstance().getTime()));
    System.out
        .println(MessageFormat.format("{0,date,yyyyMMdd} {0,time,HHmmss.SSS}",
            Calendar.getInstance().getTime()));
    System.out.println(
        MessageFormat.format("{0,date,yyyy/MM/dd} {0,time,HH:mm:ss.SSS}",
            Calendar.getInstance().getTime()));
    System.out.println(MessageFormat.format("Hello\nWorld,%n {0}", "Mike"));
  }
}

出力結果

Test001、Test002、1,000、1000、100.0%
Test101、Test101、Test102
{0}、{2, 3}、'Test101'、Test102
100000/ 100000
0027/ 0027
2018/04/10 21:33:56
20180410 213356.952
2018/04/10 21:33:56.953
Hello
World,%n Mike

■ MessageFormat あれこれ

 * 結局は、以下のAPI仕様が役に立つかもしれんが...
https://docs.oracle.com/javase/jp/6/api/java/text/MessageFormat.html

ゼロ埋め

使用する際は、以下の「■ 使用上の注意」の[3]を参照しておくといいかも
int value = 20;

// 「value = "00020"」
String value = MessageFormat.format("{0,number,00000}", value);


関連記事

Javaの文字列の扱い

http://blogs.yahoo.co.jp/dk521123/13687446.html