序列化和反序列化

1.序列化 ObjectOutputStream

序列化 步骤:

1. 被序列化的对象必须要实现接口:Serializable

        Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,

        会抛出NotSerializableException

2. 调用 ObjectOutputStream 的 writeObject方法 即可完成序列化

3. 需要注意的是:序列化Fruit对象必须要保证Fruit中的每一个属性都是可以被序列化的,否则会序列化失败

        如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,

        使用transient 关键字修饰。

ObjectOutputStream:将Java对象的原始数据类型写入到文件,实现对象的持久存储。

public ObjectOutputStream(OutputStream out): 创建一个指定OutputStream的ObjectOutputStream。

FileOutputStream fileOut = new FileOutputStream("employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);

public class Fruit implements Serializable {
    private String fname ;
    private Integer price ;
    private Integer fcount ;
    private String remark ;

    public Fruit() {
    }

    public Fruit(String fname, Integer price, Integer fcount, String remark) {
        this.fname = fname;
        this.price = price;
        this.fcount = fcount;
        this.remark = remark;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Integer getFcount() {
        return fcount;
    }

    public void setFcount(Integer fcount) {
        this.fcount = fcount;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "fname='" + fname + '\'' +
                ", price=" + price +
                ", fcount=" + fcount +
                ", remark='" + remark + '\'' +
                '}';
    }
}
public class Demo4 {
    public static void main(String[] args) throws IOException {
        Fruit fruit = new Fruit("苹果",5,100,"苹果很好吃");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Day19-io/src/fruit.dat"));
        oos.writeObject(fruit);
        oos.close();
    }
 
}

2. 反序列化 ObjectInputStream

//序列化:ObjectOutputStream -> oos.writeObject()

//反序列化: ObjectInputStream -> ois.readObject()

public class Demo6 {    
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Day19-io/src/fruit.dat"));

        Fruit fruit = (Fruit)ois.readObject();
        System.out.println(fruit);
        ois.close();

    } 
}

3. transient的作用

如果对象中的某个属性在序列化到磁盘时,不打算将这个属性序列化进去,那么我们使用transient来修饰这个属性

public class Person implements Serializable {
    private String name;
    private transient String pwd;
    private String address;

    public Person() {
    }

    public Person(String name, String pwd, String address) {
        this.name = name;
        this.pwd = pwd;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
public class Demo7 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person person = new Person("小明","5987382","上海");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Day19-io/src/person.dat"));
        oos.writeObject(person);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Day19-io/src/person.dat"));
        Object obj = ois.readObject();
        System.out.println(obj);  //Person{name='小明', pwd='null', address='上海'}
    }
}

4. 版本号:

Serializable 接口给需要序列化的类,提供了一个序列版本号。serialVersionUID 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。

private static final long serialVersionUID = 1L;

public class Fruit implements Serializable {
    private static final long serialVersionUID = 1L;
    private String fname ;
    private Integer price ;
    private Integer fcount ;
    private String remark ;

    public Fruit() {
    }

    public Fruit(String fname, Integer price, Integer fcount, String remark) {
        this.fname = fname;
        this.price = price;
        this.fcount = fcount;
        this.remark = remark;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Integer getFcount() {
        return fcount;
    }

    public void setFcount(Integer fcount) {
        this.fcount = fcount;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "fname='" + fname + '\'' +
                ", price=" + price +
                ", fcount=" + fcount +
                ", remark='" + remark + '\'' +
                '}';
    }
}

5. Externalizable

ublic class Car implements Externalizable {
    private Integer cid ;
    private String cname ;
    private Integer price ;
    private String address ;

    public Car() {
    }

    public Car(Integer cid, String cname, Integer price, String address) {
        this.cid = cid;
        this.cname = cname;
        this.price = price;
        this.address = address;
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Car{" +
                "cid=" + cid +
                ", cname='" + cname + '\'' +
                ", price=" + price +
                ", address='" + address + '\'' +
                '}';
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(this.cid);
        out.writeUTF(this.cname);
        out.writeInt(this.price*2);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.cid = in.readInt();
        this.cname = in.readUTF();
        this.price = in.readInt();
        this.address = "地址保密";
    }
}
public class Demo8 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Car car = new Car(1,"大众宝来",99,"德国");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Day19-io/src/car.dat"));
        oos.writeObject(car);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Day19-io/src/car.dat"));
        System.out.println(ois.readObject());
        ois.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值