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 ランタイム環境 (ビルド 1.7.0_07-b11)

于 2012-10-03T09:13:33.613 に答える