关于对象序列化和反序列化

“序列化”是一种把对象的状态转化成字节流的机制,“反序列”是其相反的过程,把序列化成的字节流用来在内存中重新创建一个实际的Java对象。这个机制被用来“持久化”对象。通过对象序列化,可以方便的实现对象的持久化储存以及在网络上的传输。

对象序列化流:ObjectOutputStream;

 由帮助文档知道ObjectOutputStream将原石数据类型和图形写入OutputStream;可读取或重构对象

对象需要实现Serializable接口才能写入流中

writeObject(Object obj)方法可将指定对象写入ObjectOutputStream.


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream foo=new ObjectOutputStream(new FileOutputStream("D:/666/He.java"));
        Goods s=new Goods("kele",10000);
        foo.writeObject(s);
        foo.close();
    }
}

​

public class Goods {
    private String name;
    private int price;

    public Goods() {
    }
    public Goods(String name,int price)
    {this.name=name;
    this.price=price;}
    public String getName() {
        return name;}

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

    public int getPrice() {
        return price;
    }

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

运行会报错:

Exception in thread "main" java.io.NotSerializableException: Goods
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at Main.main(Main.java:12)

上面Goods没有实现Serializable接口;所以会报错;使之implements Serializable;但Serializable接口里不含任何抽象方法,所以它不需要重写方法

运行后文件内容变为: sr Goods钑姍nI I priceL namet Ljava/lang/String;xp  't kele   显然除了一些字符外我们无法识别此对象

当然,与其他流一样,一旦打开就不要忘记关闭!!!!!!!

对象反序列化流:ObjectInputStream:

它可反序列化之前使用ObjectOutputStream编写的原始数据和对象。

import java.io.*;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[]args) throws IOException, ClassNotFoundException {
        ObjectInputStream fis=new ObjectInputStream(new FileInputStream("D:/666/He.java"));
        Object obj=fis.readObject();
        Goods s=(Goods)obj;
        System.out.println(s.getName()+"     "+s.getPrice());
        fis.close();
        }}

得到了对象中的属性;输出了可乐和它的价格。

用对象序列化流序列化了一个对象后如果修改了对象所属类文件,

import java.io.*;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[]args) throws IOException, ClassNotFoundException
    {write();
        read();
    }

        public static void write()throws IOException {
            ObjectOutputStream foo=new ObjectOutputStream(new FileOutputStream("D:/666/He.java"));
            Goods s=new Goods("kele",10000);
            foo.writeObject(s);
            foo.close();}
            public static void read() throws IOException, ClassNotFoundException {
                ObjectInputStream fis=new ObjectInputStream(new FileInputStream("D:/666/He.java"));
                Object obj=fis.readObject();
                Goods s=(Goods)obj;
                System.out.println(s.getName()+"     "+s.getPrice());
                fis.close();
            }
        }
import java.io.Serializable;

public class Goods implements Serializable {
    private String name;
    private int price;

    public Goods() {
    }
    public Goods(String name,int price)
    {this.name=name;
    this.price=price;}
    public String getName() {
        return name;}

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

    public int getPrice() {
        return price;
    }

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

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

如代码所示,先注释掉read方法,用write写入对象,然后重写Goods中的toString方法,再用read读取文件会报出错误

Exception in thread "main" java.io.InvalidClassException: Goods; local class incompatible: stream classdesc serialVersionUID = -1687161514635671270, local class serialVersionUID = 789728371662175168
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2028)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1875)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2209)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1692)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:508)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:466)
	at Main.read(Main.java:18)
	at Main.main(Main.java:8)

修改类文件会导致serialVersionUID改变;会报错;如需除去此异常,必须在Good类中显示定义serialVersionUID的值;加上private static final long serialVersionUID=41l;即可。

如果不想某个成员变量值被序列化;加上关键字transient即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值