簡體   English   中英

XML序列化和空構造函數

[英]XML Serialization and Empty Constructors

我有以下允許我序列化程序中對象的類:

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Persistor<T> {

    private T data;

    public void save(T data, String file) {

        try {

            FileOutputStream os = new FileOutputStream(file);
            XMLEncoder encoder = new XMLEncoder(os);
            encoder.writeObject(data);
            encoder.close();

        } catch(FileNotFoundException e) {

            System.out.println("File not found");

        }

    }

    @SuppressWarnings({ "unchecked", "finally" })
    public T read(String file) {

        try {

            FileInputStream fis = new FileInputStream(file);
            XMLDecoder decoder = new XMLDecoder(fis);
            data = (T)decoder.readObject();
            decoder.close();

        } catch(FileNotFoundException e) {

            System.out.println("File not found");

        } finally {

            return data;

        }

    }

}

問題是我的商務邏輯包中有像Student這樣的類,並且看來我需要有一個空的構造函數public Student() {}才能使程序正常工作:

package logic;

public class Student {

    private String name;

    public Student(String name) {

        this.name = name;

    } public Student() {} // empty constructor

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String toString() {

        return name;

    }

}

如果我取出空的構造函數,則控制台上會出現以下異常:

java.lang.InstantiationException: logic.Student
Continuing ...
java.lang.IllegalStateException: The outer element does not return value
Continuing ...

有什么辦法可以解決這個問題,我的意思是沒有空的構造函數? 因為我喜歡另外7個類,每個人都需要擁有自己的空構造函數。

您可以嘗試使用ConstructorProperties批注

public class Student {
    private String name;

    @ConstructorProperties("name")
    public Student(String name) {
        this.name = name;
    } 

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

測試

public class Test1 {

    public static void main(String[] args) throws Exception {
         Student s1 = new Student("Jon");
         XMLEncoder encoder = new XMLEncoder(new FileOutputStream("xxx"));
         encoder.writeObject(s1);
         encoder.close();

         XMLDecoder decoder = new XMLDecoder(new FileInputStream("xxx"));
         Student s2 = (Student)decoder.readObject();
         decoder.close();
         System.out.println(s2);
    }
}

產量

test.Student@e3fd79

您正在嘗試反序列化bean。 包括XMLEncoder / Decoder在內的大多數序列化框架執行此操作的方式是,實例化默認的no-arg構造函數,然后反射性地為每個成員對象調用getter或setter。

該文檔似乎支持這一點。

XMLDecoder javadoc

XMLDecoder類用於讀取使用XMLEncoder創建的XML文檔,並且與ObjectInputStream一樣使用。

ObjectInputStream javadoc

讀取對象類似於運行新對象的構造函數。 為對象分配內存,並將其初始化為零(NULL)。 為不可序列化的類調用無參數構造函數,然后從流中恢復可序列化類的字段,該流從最接近java.lang.object的可序列化類開始,並以該對象的最特定類結束。

...

序列化不會讀取任何值或將值分配給任何未實現java.io.Serializable接口的對象。 不可序列化的對象的子類可以被序列化。 在這種情況下,不可序列化的類必須具有no-arg構造函數,以允許對其字段進行初始化。 在這種情況下,子類負責保存和恢復不可序列化類的狀態。 通常,該類的字段是可訪問的(公共,程序包或受保護),或者存在可用於還原狀態的get和set方法。

從文檔中,您可以看到您的選項是實現Serializable還是添加no-arg構造函數,並保留所有字段的getter和setter。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM