代码之家  ›  专栏  ›  技术社区  ›  dimo414

{0}和{0,number,integer}之间有什么区别

  •  4
  • dimo414  · 技术社区  · 14 年前

    我正在努力了解更多关于Java的 MessageFormat 实用程序,在我们的代码库和其他地方的示例中,我看到了两者 {0} 和 {0,number,integer} 用于数字,但我不确定哪一个更可取。

    打印差异的快速测试:

    import java.text.MessageFormat;
    import java.text.NumberFormat;
    import java.util.Locale;
    
    public class MessageFormatTest
    {
        public static void main(String[] args){
            MessageFormat simpleChoiceTest = new MessageFormat("{0}");
            MessageFormat explicitChoiceTest = new MessageFormat("{0,number,integer}");
            int[] set = new int[]{0,1,4,5,6,10,10000,24345};
            Locale[] locs = new Locale[]{Locale.US,Locale.UK,Locale.FRANCE,Locale.GERMANY};
            for(Locale loc : locs){
                simpleChoiceTest.setLocale(loc);
                explicitChoiceTest.setLocale(loc);
                for(int i : set){
                    String simple = simpleChoiceTest.format(new Object[]{i});
                    String explicit = explicitChoiceTest.format(new Object[]{i});
                    if(!simple.equals(explicit)){
                        System.out.println(loc+" - "+i+":\t"+simple+
                            "\t"+NumberFormat.getInstance(loc).format(i));
                        System.out.println(loc+" - "+i+":\t"+explicit+
                            "\t"+NumberFormat.getIntegerInstance(loc).format(i));
                    }
                }
            }
        }
    }
    

    输出:

    fr_FR - 10000:  10 000  10 000
    fr_FR - 10000:  10,000  10 000
    fr_FR - 24345:  24 345  24 345
    fr_FR - 24345:  24,345  24 345
    de_DE - 10000:  10.000  10.000
    de_DE - 10000:  10,000  10.000
    de_DE - 24345:  24.345  24.345
    de_DE - 24345:  24,345  24.345
    

    这让我很惊讶,如果有什么不同的话 {0} 不要对数字做任何事情 {0,number,integer} 以正确地对其进行本地化。相反,两者都进行了本地化,但显式形式似乎总是使用en_US本地化。

    根据链接的文献, {0} 接通 NumberFormat.getInstance(getLocale()) 而显式形式使用 NumberFormat.getIntegerInstance(getLocale()) 然而,当我直接调用它们(输出中的最后一列)时,它们看起来完全相同,并且都正确地本地化了。

    我在这里错过了什么?

    2 回复  |  直到 14 年前
        1
  •  1
  •   dimo414    12 年前

    你是对的。当您使用“MessageFormat(”{0,number,integer}“)”时,格式化程序在初始化时使用默认区域设置(en_US),并且数字在默认区域设置中标记为使用integer格式(en_US),因为下面的代码是在初始化时间执行的。

    // this method is internally called at the time of initialization
    MessageFormat.makeFormat()
    // line below uses default locale if locale is not
    // supplied at initialization (constructor argument) 
    newFormat = NumberFormat.getIntegerInstance(locale);
    

    由于您是在之后设置区域设置的,因此对分配给数字的格式模式没有影响。如果您想在数字格式中使用所需的语言环境,请在初始化时使用语言环境参数,例如:

    MessageFormat test = new MessageFormat("{0,number,integer}", Locale.FRANCE);
    
        2
  •  0
  •   Víctor Herraiz    14 年前

    在我看来,这是一个Java错误(接口错误)或文档问题。您应该在Oracle打开一个新问题来纠正这一问题。

    正如Yogendra Singh所说,格式化程序(DecimalFormat)的实例是在MessageFormat构造函数时创建的。

    MessageFormat simpleChoiceTest = new MessageFormat("{0}");
    System.out.println(simpleChoiceTest.getFormatsByArgumentIndex()[0]);
    //Prints null
    MessageFormat explicitChoiceTest = new MessageFormat("{0,number,currency}");
    System.out.println(explicitChoiceTest.getFormatsByArgumentIndex()[0]);
    //Prints java.text.DecimalFormat@67500
    

    调用MessageFormat.setLocale时,它不会更改其内部格式化程序的区域设置。

    至少应该更改文档以反映此问题。

    这是我的java版本: java版本“1.7.0_07” Java(TM)SE运行时环境(内部版本1.7.0_07-b11)

    推荐文章