对象序列化与反序列化

对象序列化

哈喽大家好这里是狗蛋子,今天让我们讨论一下对象序列化的知识体系。
我现在就是想问大家一个问题,大家众所周知,new出来的对象是在内存中存放着,但是假如我现在要通过网络传输给你,我该怎么做?这样说未免太生涩了,我举个例子理解一下:假如你在一家餐馆,你在前台点菜了,老板通过网络将你想吃的菜肴发送给了后厨,后厨就能将你的饭菜做好,你知道这怎么实现的么?不知道就对啦! 当然你知道肯定是更好哈哈哈哈,好了不开玩笑,今天就和大家探讨一下这个问题:


序列化和反序列化

序列是将对象的状态信息转化为可以存储或者可以网络传输的形式的过程。一般将一个对象存储到一个储存媒介,例如档案或记忆体缓冲等,在网络传输过程中,可以是字节或者XML等格式;而字节或者XML格式的可以还原成完全相等的对象,这个相反的过程又称为反序列化。


首先,java是支持这个事件发生的,意思就是说,java有这样一个功能,首先我们要了解,实现功能一般都是有一个类或者一个接口能完成这项任务,这里我们就需要实现一个接口,这里的接口叫做:java.io.Serializable,Java类通过实现java.io.Serialization接口来启用序列化功能,未实现此接口的类将无法将其任何状态或者信息进行序列化或者反序列化。可序列化类的所有子类型都是可以序列化的。序列化接口没有方法或者字段,仅用于标识可序列化的语义。只要你实现这个接口,JVM就会将你的信息序列化,你就可以将信息通过网络传输,然后到了终点站以后再反序列化还原你发的信息,这样就可以将内存中的实例通过网络传输了。当试图对一个对象进行序列化时,如果遇到一个没有实现java.io.Serialization接口的对象时,将抛出NotSerializationException异常。


以前会用上面的方式进行传输,现在能力升级了,可以通过json就可以实现这个功能,现在会搭建Rest服务,在网际之间传输json,然后设计成Restful接口来完成这件事。聊天传输的一条条消息不是一条条实例,而是JavaScript对象,叫做json,现在都用FastJson这个阿里巴巴开发的组件完成。当然,以后随着深入学习,你会了解这个的,现在只是普及一下这个知识点。


但是我们还是得继续学习一下这个序列化和反序列化的过程
首先我们创建一个Student类,学生有ID,name等参数,然后写好构造函数还有get()set()方法:

public class Stu implements java.io.Serializable {
        private static final long serialVersionUID = 8918676416282216936L;
        private int id;
        private String name;

    public Stu(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Stu(){}

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

之后新创建一个类TestCase用于模拟序列化和反序列化:

public class TestCase {
    public static void main(String[] args) throws Exception{
        Stu stu = new Stu(2,"jack");
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("src/com/hzy/IO/data/stu.data"));
        out.writeObject(stu);

        Stu stu2 = new Stu();
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("src/com/hzy/IO/data/stu.data"));

        stu2 =(Stu)in.readObject();
        System.out.println(stu2);
    }
}

我来解释一下代码,首先大家看,这里的输出流不再是FileOutputStream了。而是ObjectOutputStream,这个可是个高级流——对象输出流。相当于你把这个Jack同学写进指定目录里,然后又声明一个stu2,里面什么成员变量也没写,然后用一个ObjectInputStream目录里面那个已经序列化的文件——stu.data,然后把读到的对象转化成stu2,然后再把stu2输出,这时,stu和stu2表示的对象是一样的这样就反序列化了。
在这里插入图片描述


这里再说一个关键字:transient,是这样使用的:

private int id;
private transient String name;

因为有这个关键字,所以GC回收会非常快,所以有这个关键字的成员变量就不参与序列化。可以控制需要序列化的成员变量有哪些。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值