公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
序列化是将对象的状态信息转换为可存储或可传输的形式的过程,简而言之,把对象转换为字节数组的过程称之为对象的序列化。反序列化即序列化的逆过程。把字节数组恢复为对象的过程称为对象的反序列化。
序列化使用场景
- 通过将对象序列化为字节数组,使得不共享内存、通过网络连接的系统之间能够进行对象的传输。
- 通过将对象序列化为字节数组,能够将对象永久存储到存储设备。
- 解决远程接口调用 jvm 之间内存无法共享的问题。
评价序列化算法优劣的两个指标
- 序列化后码流的大小。
- 序列化本身的速度以及系统资源开销的大小(包括内存、cpu 等)。
java 序列化实现
先定义一个公共接口。
package com.xttblog.rpc.serialization.base; // 业余草:www.xttblog.com public interface MySerializer { /** * 序列化 * @param obj * @param <T> * @return */ <T> byte[] serialize(T obj); /** * 反序列化 * @param data * @param clazz * @param <T> * @return */ <T> T deserialize(byte[] data, Class<T> clazz); }
使用 java 原生的方式实现该接口。
package com.xttblog.rpc.serialization; import com.xttblog.rpc.serialization.base.JavaSerializerModel; import com.xttblog.rpc.serialization.base.JavaSerializerModel2; import com.xttblog.rpc.serialization.base.MySerializer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class JavaSerialization implements MySerializer{ @Override public <T> byte[] serialize(T obj) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(obj); objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } return byteArrayOutputStream.toByteArray(); } @Override public <T> T deserialize(byte[] data, Class<T> clazz) { ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data); try { ObjectInputStream objectInputStream= new ObjectInputStream(byteArrayInputStream); return (T) objectInputStream.readObject(); } catch (Exception e) { throw new RuntimeException(); } } public static void main(String[] args) { JavaSerialization javaSerialization = new JavaSerialization(); JavaSerializerModel serializerModel = new JavaSerializerModel(); JavaSerializerModel model = javaSerialization.deserialize(javaSerialization.serialize(serializerModel), JavaSerializerModel.class); System.out.println(model.getName()); System.out.println(model.getPhone()); System.out.println("------model2--------"); JavaSerializerModel2 serializerModel2 = new JavaSerializerModel2(); JavaSerializerModel2 model2 = javaSerialization.deserialize(javaSerialization.serialize(serializerModel2), JavaSerializerModel2.class); System.out.println(model2.getName()); System.out.println(model2.getPhone()); } }
java 的序列化主要是通过 OutputStream 与 InputStream 来实现的,被序列化的类需要实现 java.io.Serializable 接口。
上述的实现代码是使用 java 进行序列化与反序列化的通用代码。
关于 java 序列化的其他知识点
- 序列化时,只对对象的状态进行保存,而不管对象的方法。
- 当一个父类实现序列化时,子类自动实现序列化,不需要显示的实现 Serializable 接口。
- 当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化。
- 当某个字段被声明为 transient 后,默认的序列化机制会忽略该字段。
- 当某个字段被声明为 transient 后,如果想序列化该字段,需在类中添加 writeObject() 与 readObject() 方法。
序列化测试
JavaSerializerModel.java
package com.xttblog.rpc.serialization.base; import java.io.Serializable; public class JavaSerializerModel implements Serializable { private transient String name = "业余草"; private String phone = "www.xttblog.com"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
JavaSerializerModel2.java
package com.xttblog.rpc.serialization.base; import java.io.Serializable; public class JavaSerializerModel implements Serializable { private transient String name = "业余草"; private String phone = "www.xttblog.com"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
测试类 Main.java
public static void main(String[] args) { JavaSerialization javaSerialization = new JavaSerialization(); JavaSerializerModel serializerModel = new JavaSerializerModel(); JavaSerializerModel model = javaSerialization.deserialize( javaSerialization.serialize(serializerModel), JavaSerializerModel.class); System.out.println(model.getName()); System.out.println(model.getPhone()); System.out.println("------model2--------"); JavaSerializerModel2 serializerModel2 = new JavaSerializerModel2(); JavaSerializerModel2 model2 = javaSerialization.deserialize( javaSerialization.serialize(serializerModel2), JavaSerializerModel2.class); System.out.println(model2.getName()); System.out.println(model2.getPhone()); }
测试结果:
null www.xttblog.com ------model2-------- 业余草 www.xttblog.com
可以看到,添加 writeObject() 与 readObject() 方法后,transient 字段也被正确序列化了。
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » java 序列化教程