MessageFormat用法


一、前言                              

  String.format 用得不習慣,希望格式模版會這樣 {0}, this is {1}s cat.{1},this is {0}s dog. 后來發現 java.text.MessageFormat.format 可以滿足我這個小小的願望。

 

二、靜態方法

String MessageFormat.format(String fmt, Object...args)

  入參fmt為MessageFormat模式參數。

 

三、MessageFormat模式                      

  格式:  

 ArgumentIndex[,FormatType[,FormatStyle]] 

  ArgumentIndex ,是從0開始的入參位置索引。

  FormatType ,指定使用不同的Format子類對入參進行格式化處理。值范圍如下:

     number:調用NumberFormat進行格式化

     date:調用DateFormat進行格式化

     time:調用DateFormat進行格式化

     choice:調用ChoiceFormat進行格式化

  FormatType ,設置FormatType中使用的格式化樣式。值范圍如下:

    short,medium,long,full,integer,currency,percent,SubformPattern(子格式模式,形如#.##)

  注意: FormatType 和 FormatStyle 主要用於對日期時間、數字、百分比等進行格式化。

  示例——將數字1.23格式為1.2:

double num = 1.23;
String str = MessageFormat.format("{0,number,#.#}", num);

 

四、MessageFormat注意點                    

  1. 兩個單引號才表示一個單引號,僅寫一個單引號將被忽略。

  2. 單引號會使其后面的占位符均失效,導致直接輸出占位符。

MessageFormat.format("{0}{1}", 1, 2); // 結果12
MessageFormat.format("'{0}{1}", 1, 2); // 結果{0}{1}
MessageFormat.format("'{0}'{1}", 1, 2); // 結果{0}

因此可以用於輸出左花括號(單寫左花括號會報錯,而單寫右花括號將正常輸出)

MessageFormat.format("'{'{0}}", 2); // 結果{2

因此前言中的示例應該寫為

{0}, this is {1}''s cat.{1},this is {0}''s dog.

 

五、類層級關系                                

                            

                        |-- java.text.MessageFormat

頂層抽象類java.text.Format—
| |--java.text.ChoiceFormat   |--java.text.NumberFormat—|                                      |--java.text.DecimalFormat |--java.text.DateFormat—java.text.SimpleDateFormat

 

   1. DecimalFormat

       用於格式化十進制實數。通過格式字符串來自定義格式化類型,舍入方式為half-even(四舍五入)。

       格式化模式: 

    正數子模式;負數子模式 ,如 0.00;-0.00 ,簡寫為 0.00 。

       模式中的占位符:

    0 ,代表該為位為數字,若不存在則用0填充

         # ,代表該為位為數字

    , ,代表分隔符, 如模式為 #,# ,那么格式化10時會返回1,0

   2. ChoiceFormat

    相當於以數字為鍵,字符串為值的鍵值對。分別使用一組double類型的數組作為鍵,一組String類型的數組作為值,兩數組相同索引值的元素作為一對。

    示例——基本用法

復制代碼
double[] limit = {0,1,3};
String[] format = {"hello0", "hello1", "hello3"};
ChoiceFormat cf = new ChoiceFormat(limit, format);
for(int i = 0; i < 4; ++i){
  System.out.println(cf.format(i));
}
/* 輸出
 * hello0
 * hello1
 * hello0
 * hello3
 */
復制代碼

   注意:當找不到對應的鍵值對時,則使用第一或最后一對鍵值對。

   示例——結合MessageFormat使用

復制代碼
double[] limit = {0, 1};
String[] format = {"Hello0", "Hello1{1}"};
ChoiceFormat cf = new ChoiceFormat(limit, format);
MessageFormat mf = new MessageFormat("{0}");
mf.setFormatByArgumentIndex(0, cf);
for (int i = 0; i < 2; ++i){
    System.out.println(mf.format(new Object[]{new Integer(i), new Integer(i+1)}));
}
/* 輸出
 * Hello0
 * Hello12
 */
復制代碼

 

六、性能問題                                  

  由於靜態方法 MessageFormat.format 內部是

public static String format(String pattern, Object ... arguments)   
{  
    MessageFormat temp = new MessageFormat(pattern);  
    return temp.format(arguments);  
}  

  因此若要多次格式同一個模式的字符串,那么創建一個MessageFormat實例在執行格式化操作比較好些。

 

七、總結                                  

  對於簡單的格式化或字符串組裝,MessageFormat.format方法 使用更方便些,但要格式化處理更豐富的話要是用 String.format方法.

  尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4095059.html  ^_^肥仔John  

---------------------------------------------------------------------------------------------------------------------------------------
MessageFormatMessageFormat.format 

MessageFormat用來格式化一個消息,通常是一個字符串,比如:

String str = "I'm not a {0}, age is {1,number,short}", height is {2,number,#.#};

而MessageFormat可以格式化這樣的消息,然后將格式化后的字符串插入到模式中的適當位置,比如:

將str中的{0}用"pig"替換,{1,number,short}用數字8替換,{2,number,#.#}用數字1.2替換。

那么最終用戶得到的是一個格式化好的字符串"I'm not a pig, age is 8, height is 1.2"。

 

MessageFormat本身與語言環境無關,而與用戶提供給MessageFormat的模式和用於已插入參數的子格式模式有關,以生成適用於不同語言環境的消息。

 

MessageFormat模式(主要部分): 

 

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

 

 FormatType
         number

         date

         time

         choice(需要使用ChoiceFormat)

 

 FormatStyle:
         short
         medium
         long
         full
         integer
         currency
         percent
         SubformatPattern(子模式)

 

還以str為例,在這個字符串中:

1、{0}和{1,number,short}和{2,number,#.#};都屬於FormatElement,0,1,2是ArgumentIndex。

2、{1,number,short}里面的number屬於FormatType,short則屬於FormatStyle。

3、{1,number,#.#}里面的#.#就屬於子格式模式。

指定FormatTypeFormatStyle是為了生成日期格式的值、不同精度的數字、百分比類型等等。

 

實例:

1、ArgumentIndex必須是非負整數,它的個數不只限於0到9這10個,它可以用0到9的數字組成,因此可以有好多個,如:

Java代碼
String pig = "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}";  
  
Object[] array = new Object[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q"};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

最終結果是:ABCDEFGHIJKLMNOPQ

 

2、格式化字符串時,兩個單引號才表示一個單引號,單個單引號會被省略,如:

Java代碼:
  
String message = "oh, {0} is 'a' pig";  
  
Object[] array = new Object[]{"ZhangSan"};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

 最終結果是:oh, ZhangSan is a pig

 

給字母a加上單引號,如:

Java代碼  
String message = "oh, {0} is ''a'' pig";  
  
Object[] array = new Object[]{"ZhangSan"};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 最終結果是:oh, ZhangSan is 'a' pig

 

3、單引號會使某個字符或串保持原形。

     所以,假如沒有特殊要求,一般都是要在正式格式化之前把單引號都去掉,否則會造成不必要的麻煩,如:

Java代碼  
String message = "oh, '{0}' is a pig";  
  
Object[] array = new Object[]{"ZhangSan"};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

 最終結果是:oh, {0} is 'a' pig,此處ZhangSan無法顯示。

 

 又如,使用子格式模式,多了一個單引號:

Java代碼  
String message = "oh, '{0,number,#.#} is a pig";  
  
Object[] array = new Object[]{new Double(3.1415)};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

 最終結果是:oh, {0,number,#.#}  is 'a' pig。

 

 如果像下面這樣,就可以正確顯示:

Java代碼  
String message = "oh, {0,number,#.#} is a pig";  
  
Object[] array = new Object[]{new Double(3.1415)};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

 最終結果是:oh, 3.1 is a pig

 

3、無論是有引號字符串還是無引號字符串,左花括號都是不支持的,但支持右花括號顯示,如:

Java代碼  
String message = "oh, { is a pig";  
  
Object[] array = new Object[]{"ZhangSan"};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

 最終結果是:異常java.lang.IllegalArgumentException: Unmatched braces in the pattern

 

右花括號可以顯示,如:

Java代碼  
String message = "oh, } is a pig";  
  
Object[] array = new Object[]{"ZhangSan"};  
  
String value = MessageFormat.format(message, array);  
  
System.out.println(value);  

 

 最終結果是:oh, } is a pig

 

 

關於MessageFormat.format方法:

每調用一次MessageFormat.format方法,都會新創建MessageFormat的一個實例,相當於MessageFormat只使用了一次。MessageFormat類的format方法如下:

Java代碼 
public static String format(String pattern, Object ... arguments)   
{  
    MessageFormat temp = new MessageFormat(pattern);  
    return temp.format(arguments);  
}  

 

如果要重復使用某個MessageFormat實例,可以用如下方式:

Java代碼  
String message = "oh, {0} is a pig";  
  
MessageFormat messageFormat = new MessageFormat(message);  
  
Object[] array = new Object[]{"ZhangSan"};  
  
String value = messageFormat.format(array);  
  
System.out.println(value);  

 

 最終結果是:oh, ZhangSan is a pig

 

 在Java程序中做字符串拼接時一定要記得的MessageFormat.format

 

Java里從來少不了字符串拼接的活,Java程序員也肯定用到過StringBuffer,StringBuilder,以及被編譯器優化掉的+=。但這些都和下文要談的無關。

比如有這樣的字符串:

張三將去某地點找李四。

其中,張三某地點和李四都是可變的,比如張三變成王五,某地點變成紐約,李四變成趙六。於是整句變成:

王五將去紐約找趙六。

如果直接將張三,某地點和李四用變量替代,再拼接起來,可以達到目的。但是,代碼不好寫,也不好看,也不好維護。但是,我看過很多SQL拼接,HTML拼接都是這樣做的。我自己以前也是這樣,自從接觸了MessageFormat.format之后才意識到有更好的形式。請看下面的代碼:

String[] tdArr=...;            
String result=MessageFormat.format("<tr bgcolor='#cef'><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>", tdArr);

這段代碼將把數組tdArr中的四個元素分別插入到{0},{1},{2},{3}的位置。

你看看,是不是這樣形式和內容有效的分開了。容易想象,當元素增多時,這種方式優勢很明顯。

一件事有很多手段來達成,知道那種手段更好,是你經驗的體現和專業化的特征。

補記:

如果字符串需要輸出單引號',可以用兩個單引號''進行轉義,下面代碼請參考:

public int insertToTest_tb(String createTime,String datefrom,String dateto,String name,String intranetid,String actualhour,String planhour,String status) throws Exception{
        StringBuilder sb=new StringBuilder();
        sb.append("    insert into test_tb (");
        sb.append("        createTime, ");
        sb.append("        datefrom, ");
        sb.append("        dateto, ");
        sb.append("        name, ");
        sb.append("        intranetid, ");
        sb.append("        actualhour, ");
        sb.append("        planhour, ");
        sb.append("        status");
        sb.append("    ) values (");
        sb.append("        ''{0}'',");
        sb.append("        ''{1}'',");
        sb.append("        ''{2}'',");
        sb.append("        ''{3}'',");
        sb.append("        ''{4}'',");
        sb.append("        ''{5}'',");
        sb.append("        ''{6}'',");
        sb.append("        ''{7}''");
        sb.append("    )");
        String result=sb.toString();
        
        Object[] arr={createTime,datefrom,dateto,name,intranetid,actualhour,planhour,status};
        String sql=MessageFormat.format(result, arr);
        
        return this.getJdbcTemplate().update(sql);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM