序列化繼承

mingwulipo發表於2019-04-23

相關注意事項
a)序列化時,只對物件的狀態進行儲存,而不管物件的方法;
b)當一個父類實現序列化,子類自動實現序列化,不需要顯式實現Serializable介面;
c)當一個物件的例項變數引用其他物件,序列化該物件時也把引用物件進行序列化;但是該物件也要實現序列化介面
d)並非所有的物件都可以序列化,至於為什麼不可以,有很多原因了,比如:
1.安全方面的原因,比如一個物件擁有private,public等field,對於一個要傳輸的物件,比如寫到檔案,或者進行rmi傳輸等等,在序列化進行傳輸的過程中,這個物件的private等域是不受保護的。
2. 資源分配方面的原因,比如socket,thread類,如果可以序列化,進行傳輸或者儲存,也無法對他們進行重新的資源分配,而且,也是沒有必要這樣實現。
3. 這些欄位用transient修飾,就不被序列化

當一個父類實現序列化,子類自動實現序列化,不需要顯式實現Serializable介面

package com.study.demo.serialize;

import lombok.Data;
import lombok.ToString;

import java.io.*;

/**
 * Created by e-lipo on 2019/4/23.
 */
public class SerializeTest {
    public static void main(String[] args) {
        PageForm pf = new PageForm();
        pf.setPageNum(1);
        pf.setPageSize(10);
        pf.setUserId("l23");

        try {
            FileOutputStream fos = new FileOutputStream("e:/serialize.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(pf);
            oos.close();
            System.out.println("序列化: " + pf);//序列化: PageForm(super=BaseForm(userId=l23), pageNum=1, pageSize=10)

            FileInputStream fis = new FileInputStream("e:/serialize.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            PageForm form = (PageForm)ois.readObject();
            System.out.println("反序列化: " + form);//反序列化: PageForm(super=BaseForm(userId=l23), pageNum=1, pageSize=10)
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

//父類實現序列化介面,子類自動序列化
@Data
class BaseForm implements Serializable {
    private transient String  userId;
}

@Data
@ToString(callSuper = true)
class PageForm extends BaseForm {
    private Integer pageNum;
    private Integer pageSize;
}

序列化結果
在這裡插入圖片描述

當一個物件的例項變數引用其他物件,序列化該物件時也把引用物件進行序列化

但是該物件也要實現序列化介面

package com.study.demo.serialize;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.*;

/**
 * Created by e-lipo on 2019/4/23.
 */
public class SerializeTest2 {
    public static void main(String[] args) {
        User user = new User("lipo", new Address("浙江省", "hangzhou"));

        try {
            FileOutputStream fos = new FileOutputStream("e:/serialize.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(user);
            oos.close();
            System.out.println("序列化: " + user);//序列化: User(username=lipo, address=Address(province=浙江省, city=hangzhou))

            FileInputStream fis = new FileInputStream("e:/serialize.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            User form = (User)ois.readObject();
            ois.close();
            System.out.println("反序列化: " + form);//反序列化: User(username=lipo, address=Address(province=浙江省, city=hangzhou))
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class User implements Serializable {
    private String username;
    private Address address;//類欄位也必須實現序列化介面
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Address implements Serializable {
    private String province;
    private String city;
}

父類未實現Serializable,子類實現了,序列化子類例項的時候,父類的屬性不儲存

package com.study.demo.serialize;

import lombok.Data;
import lombok.ToString;

import java.io.*;

/**
 * Created by e-lipo on 2019/4/23.
 */
public class SerializeTest3 {
    public static void main(String[] args) {
        Child pf = new Child();
        pf.setPageNum(1);
        pf.setPageSize(10);
        pf.setUserId("l23");

        try {
            FileOutputStream fos = new FileOutputStream("e:/serialize.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(pf);
            oos.close();
            System.out.println("序列化: " + pf);//序列化: Child(super=Parent(userId=l23), pageNum=1, pageSize=10)

            FileInputStream fis = new FileInputStream("e:/serialize.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Child form = (Child)ois.readObject();
            System.out.println("反序列化: " + form);//反序列化: Child(super=Parent(userId=null), pageNum=1, pageSize=10)
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


@Data
class Parent{
    private String userId;
}

//父類沒有實現序列化,子類實現序列化,子類序列化時,父類屬性值丟失
@Data
@ToString(callSuper = true)
class Child extends Parent implements Serializable {
    private Integer pageNum;
    private Integer pageSize;
}

transient關鍵字修飾的屬性不序列化

package com.study.demo.serialize;

import lombok.Data;
import lombok.ToString;

import java.io.*;

/**
 * Created by e-lipo on 2019/4/23.
 */
public class SerializeTest {
    public static void main(String[] args) {
        PageForm pf = new PageForm();
        pf.setPageNum(1);
        pf.setPageSize(10);
        pf.setUserId("l23");

        try {
            FileOutputStream fos = new FileOutputStream("e:/serialize.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(pf);
            oos.close();
            System.out.println("序列化: " + pf);//序列化: PageForm(super=BaseForm(userId=l23), pageNum=1, pageSize=10)

            FileInputStream fis = new FileInputStream("e:/serialize.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            PageForm form = (PageForm)ois.readObject();
            System.out.println("反序列化: " + form);//反序列化: PageForm(super=BaseForm(userId=l23), pageNum=1, pageSize=null)
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

//父類實現序列化介面,子類自動序列化
@Data
class BaseForm implements Serializable {
    private String  userId;
}

@Data
@ToString(callSuper = true)
class PageForm extends BaseForm {
    private Integer pageNum;
    private transient Integer pageSize;
}

相關文章