序列化与反序列化
现今的后台服务大多是微服务架构,每个服务按照业务进行拆分,实现了服务之间的解耦,而服务之间要记性接口调用实现,服务支架要进行数据对象共享,就要把服务对象转成二进制流,通过网路传输,传送到对方服务,在把二进制流转成对象这就是是序列化,反序列化。
1
在Java中,实现序列化只要实现 java.io.Serializable 接口,就可以被序列化了。
2
对象序列化保存的是对象的"状态",即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。
static的静态变量不是不能序列化吗,怎么还输出值了,这是为什么?其实造成这样的假象是因为static属于类,得到的是JVM已经加载好的class的static变量!现在我们修改一下代码,就是我们想要的结果喽。
3
在默认的序列化实现中,Java对象中的非静态和非瞬时域都会被包括进来,而与域的可见性声明没有关系。这可能会导致某些不应该出现的域被包含在序列化之后的字节数组中,比如密码等隐私信息。由于Java对象序列化之后的格式是固定的,其它人可以很容易的从中分析出其中的各种信息。对于这种情况,一种解决办法是把域声明为瞬时的,即使用transient关键词,另外一种做法是添加一个serialPersistentFields。
4
如果我们要自定义序列化,则必须要实现writeObject和对应的 readObject方法
5
序列化存储规则。
java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用,上面增加的 5 字节的存储空间就是新增引用和一些控制信息的空间。反序列化时,恢复引用关系, std1 和 std2 指向唯一的对象,二者相等,输出 true。该存储规则极大的节省了存储空间.
6
无论是使用transient关键字,还是使用writeObject()和readObject()方法,其实都是基于Serializable接口的序列化。JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。
Externalizable进行序列化,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。这就是为什么在此次序列化过程中Person类的无参构造器会被调用。由于这个原因,实现Externalizable接口的类必须要提供一个无参的构造器,且它的访问权限为public。
7
单列模式进行序列化,那还是单例吗?
从上面结果能发现,序列化后反序列化之后,不再是同一个对象了。其实是可以这样解释的:Java有4种创建对象的方式(new、newInstance()、clone()以及这里的readObject()方法),readObject方法就是相当于新建了一个对象,所以上面引用的会是不同的对象。如果要返回单例,只要重新readObject就可以了
序列化与反序列
1.static 属性和transient不能序列化。
2.自定义序列化,则必须要实现writeObject和对应的 readObject方法。
3.当写入文件的为同一对象时,并不会再将对象的内容进行存 储,而只是再次存储一份引用。
4.Externalizable接口如何实现。
5.序列化会破坏单例模式。卡耐基
若有侵权联系本人删除
https://www.cnblogs.com/zoucaitou/p/4164507.html
https://www.cnblogs.com/kubixuesheng/p/10350523.html
https://www.cnblogs.com/wxgblogs/p/5849951.html