初识Java序列化和反序列化

17 篇文章 0 订阅
1 篇文章 0 订阅

要实现序列化代价是非常低的,低到什么程度呢?任何类只需要实现 Serializable 这个接口就是了,并且这个接口还是一个空接口,没有定义任何方法。但真的就这么简单吗?

定义一个 User 类,包含两个字段:一个 String 类型的 name,一个 int 类型的 age 。

User user = new User("zhangsan", 10);
System.out.println("序列化之前:" + user.toString());
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.obj"));
out.writeObject(user);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.obj"));
User u = (User) in.readObject();
in.close();
System.out.println("反序列化:" + u.toString());

运行结果如图。

我们就这样完成了一个简单的序列化和反序列化的过程,是不是觉得超级简单呢?

但现在用户都比较注重隐私,不想让别人知道年龄,不想序列化 age 字段,那应该怎么办呢?关键字 transient 出场了,使用关键字 transient 修饰不想序列化的字段就可以了,这里是修饰 age 。运行结果如图。
这里写图片描述
是不是觉得这样就完?NO!!!这只是一个开始。既然我们可以指定了某些字段的是否序列化,那么我们是不是同样自定义序列化规则呢?

但是应该怎么自定义序列化规则呢?Serializable 接口是没有任何方法。那么我们就看这个接口说明吧,如图。

通俗讲,我们想要自定义序列化规则,就是实现指定的方法。

private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException {
    ObjectOutputStream.PutField putField = stream.putFields();
    putField.put("name", name);
    putField.put("age", age);
    stream.writeFields();
}

private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    ObjectInputStream.GetField getField = stream.readFields();
    name = (String) getField.get("name", null);
    age = (Integer) getField.get("age", 0);
}

运行结果如图。

可以达到和刚才一样的效果。

当然序列化还有一个最重要的东西。

private static final long serialVersionUID = 1024L;

这个最好自己声明,数字大小在合理范围内即可,如果不手动声明,这个会在序列化的时候随机生成,如果序列化和反序列胡的这个 id 不一致,会导致反序列化失败。验证方式也很简单,先序列化,然后修改 id ,接着反序列化。
这里写图片描述

序列化和反序列化还有很多的坑要踩,作者水平有限,就不展开讲解了。

PS:我其实准备了很多事例,但是那些代码报错千百怪,我自己都不能很好的解决,所以就放弃了。有兴趣的可以自己去网上搜索更多的教程。


欢迎大家关注我的微信公众号:卡戎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值