3

そこにあるすべての変数を使用して、XMLEncoder を使用して xml に適切にシリアル化するクラスを取得しました。java.util.Localeを保持するものを除きます。トリックは何でしょうか?

4

2 に答える 2

8

問題は、 java.util.Locale がBeanではないことです。XMLEncoderドキュメントから:

XMLEncoder クラスは、ObjectOutputStream の補完的な代替手段であり、ObjectOutputStream を 使用して Serializable オブジェクトのバイナリ表現を作成できるのと同じ方法で、 JavaBeanのテキスト表現を生成するために使用できます。

ただし、API を使用すると、PersistenceDelegates を使用して非 Bean タイプをシリアル化できます。

サンプル豆:

public class MyBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Locale locale;
    private String foo;

    public MyBean() {
    }

    public Locale getLocale() {
        return locale;
    }

    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

}

Locale タイプを含むデータ グラフのシリアル化:

public class MyBeanTest {

    public static void main(String[] args) throws Exception {
        // quick and dirty test

        MyBean c = new MyBean();
        c.setLocale(Locale.CHINA);
        c.setFoo("foo");

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        XMLEncoder encoder = new XMLEncoder(outputStream);
        encoder.setPersistenceDelegate(Locale.class, new PersistenceDelegate() {
            protected Expression instantiate(Object oldInstance, Encoder out) {
                Locale l = (Locale) oldInstance;
                return new Expression(oldInstance, oldInstance.getClass(),
                        "new", new Object[] { l.getLanguage(), l.getCountry(),
                                l.getVariant() });
            }
        });
        encoder.writeObject(c);
        encoder.flush();
        encoder.close();

        System.out.println(outputStream.toString("UTF-8"));

        ByteArrayInputStream bain = new ByteArrayInputStream(outputStream
                .toByteArray());
        XMLDecoder decoder = new XMLDecoder(bain);

        c = (MyBean) decoder.readObject();

        System.out.println("===================");
        System.out.println(c.getLocale());
        System.out.println(c.getFoo());
    }

}

これは、逆シリアル化でオブジェクトをインスタンス化する方法を説明するコードのセクションです。コンストラクターの引数を 3 つの文字列値に設定します。

    new PersistenceDelegate() {
        protected Expression instantiate(Object oldInstance, Encoder out) {
            Locale l = (Locale) oldInstance;
            return new Expression(oldInstance, oldInstance.getClass(),
                    "new", new Object[] { l.getLanguage(), l.getCountry(),
                            l.getVariant() });
        }
    }

詳細については、Philip Milne によるUsing XMLEncoder を参照してください。

これはさておき、ロケール情報をテキスト形式で保存し、それを使用して、必要なときに適切な Locale オブジェクトを検索する方が賢明かもしれません。そうすれば、オブジェクトをシリアル化して移植性を高めるときに、特別なケースのコードは必要ありません。

于 2008-10-12T16:57:25.170 に答える
0

すみません、java.util.Localeのことですか? javadocs によると、java.util.LocaleはSerializableを実装しているため、 langパッケージのLocaleクラスを使用しても問題はありません。

于 2008-10-12T16:14:50.653 に答える