【總結】Java序列化,反序列化實例(屬性類不實現序列化接口)

序列化是將對象狀態轉換爲可保持或傳輸的格式的過程。與序列化相對的是反序列化,它將流轉換爲對象。這兩個過程結合起來,可以輕鬆地存儲和傳輸數據。

Java中String, Integer的父類都實現了序列化接口


Person類實現了序列化接口,Person中的所有屬性也必須實現序列化接口,

package serialize;
import java.io.Serializable;

/**
 * <p>ClassName: Person<p>
 * <p>Description:測試對象序列化和反序列化<p>
 * @author 巧克力黑
 * @version 1.0 V
 * @createTime 2016-03-18
 */
public class Person implements Serializable {

    /**
     * 序列化ID
     */
    private static final long serialVersionUID = -5809782578272943999L;
    private String name;
    private Pet pet;
    
    public Person(String name, String sex, int age, Pet pet) {
        this.name = name;
        this.pet = pet;
    }

    public String getName() {
        return name;
    }

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

    public Pet getPet() {
        return pet;
    }

    public void setPet(Pet pet) {
        this.pet = pet;
    }
}

Pet類,也是Person中的一個屬性,此處Pet沒有實現Serializable

package serialize;
/**
 * 
 * @author 巧克力黑
 * @version 1.0 V
 * @createTime 2016-03-18
 *
 */
class Pet{
    private String name;
    public Pet(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return this.name;
    }
}

測試類

package serialize;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * <p>ClassName: TestSerializeAndDeserialize<p>
 * <p>Description: 測試對象的序列化和反序列<p>
 * @author 巧克力黑
 * @version 1.0 V
 * @createTime 2016-03-18
 */
public class TestSerializeAndDeserialize {
    private static Logger logger = LoggerFactory.getLogger(TestSerializeAndDeserialize.class);
    
    public static void main(String[] args) throws Exception {
        serializePerson();//序列化Person對象
        Person p = deserializePerson();//反序列Perons對象
        logger.info("name={},pet={}", p.getName(),p.getPet().toString());
    }
    
    private static void serializePerson() throws FileNotFoundException,
            IOException {
        Person person = new Person("qiaokeli", "男", 25, new Pet("旺財"));
        
        //ObjectOutputStream 對象輸出流,將Person對象存儲到E盤的Person.txt文件中,完成對Person對象的序列化操作
        ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File("E:/Person.txt")));
        oo.writeObject(person);
        logger.info("將Person序列化到文件");
        oo.close();
    }
    private static Person deserializePerson() throws Exception, IOException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("E:/Person.txt")));
        Person person = (Person) ois.readObject();
        logger.info("反序列化Person對象");
        return person;
    }
}

在Pet沒有實現Serializable接口的情況下,看看控制檯運行錯誤

Exception in thread "main" java.io.NotSerializableException: serialize.Pet
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
    at serialize.TestSerializeAndDeserialize.serializePerson(TestSerializeAndDeserialize.java:36)
    at serialize.TestSerializeAndDeserialize.main(TestSerializeAndDeserialize.java:25)

FindBugs提示錯誤

Bug: Class serialize.Person defines non-transient non-serializable instance field pet
This Serializable class defines a non-primitive instance field which is neither transient, Serializable, or java.lang.Object, and does not appear to implement the Externalizable interface or the readObject() and writeObject() methods.  Objects of this class will not be deserialized correctly if a non-Serializable object is stored in this field.
Rank: Troubling (14), confidence: HighPattern: SE_BAD_FIELD Type: Se, Category: BAD_PRACTICE (Bad practice)

結論:

由於Person中的Pet屬性沒有實現序列化接口serializable,在執行序列化,反序列化過程中就會出錯。

解決辦法就是將Pet也實現序列化接口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章