4

我试图更多地了解 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()). 然而,当我直接调用它们(输出中的最后一列)时,它们看起来都相同,并且都正确定位。

我在这里想念什么?

4

2 回答 2

1

你说的对。当您使用“MessageFormat("{0,number,integer}")”时,格式化程序在初始化时使用默认语言环境(en_US),并且数字在默认语言环境(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);

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

MessageFormat test = new MessageFormat("{0,number,integer}", Locale.FRANCE);
于 2012-10-02T20:23:35.373 回答
0

在我看来,这是一个 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 Runtime Environment (build 1.7.0_07-b11)

于 2012-10-03T09:13:33.613 回答