赞
踩
#粤嵌我来了##粤嵌星计划#
粤嵌星计划挑战
今天打卡第四十天
今天的学习内容java中io流部分中关于序列化的整理()
一、为什么需要序列化?
二、反序列化时如何生成实例
三、是不是所有的类都需要序列化
四、java序列化(Serializable)和外部化(Externalizable)的主要区别
五、哪些东西需要序列化
:不用类去显示声明无参构造方法,而是通过一种语言之外的对象创建机制
这里就有两个问题需要注意:
1。 通过序列化可以任意创建实例,不受任何限制。单例模式如果实现序列化的话,通过反序列化也可以轻松创建对象。
2. 由于不调用类自己的构造器,而是通过构造器Constructor来实现的。一些限制条件就很难满足。比如,有两个参数 max,min,构造时必须满足 max>min。如果不满足参数条件,系统存在被序列化攻击的风险。
3. 对象进行序列化时,类中所定义的被private、final等访问控制符所修饰的字段是直接忽略这些访问控制符而直接进行序列化的,因此,原本在本地定义的想要控制字段的访问权限的工作都是不起作用的。对于序列化后的有序字节流来说一切都是可见的,对象中的任何private字段几乎都是以明文的方式出现在套接字流中,这严重破坏了原有类的数据的“安全性”。幸运的是,我们可以让序列化的类可以实现一个 writeObject方法;反序列化过程,我们将在同一个类上实现一个readObject方法,通过使用writeObject 和 readObject 可以实现密码加密和签名管理
三、是不是所有的类都需要序列化
是不是所有的类都需要序列化? 如果是,则序列化就应该是类的基本功能,如果这样的话,序列化就应该对程序员彻底透明才是,所以并不是所有的类都需要序列化,原因如下:
安全问题:有的类是**敏感的**类,里面的数据不能公开。而实现了序列化就很容易被破解,可以说没有秘密可言,隐私性没有保证。
**资源问题**:序列化可以任意生成实例而不受限制,如果有的对象生成的实例是受限制的,比如只能生成10个实例,或者是单例的,这个很难保证。
所以不是所有的类都需要序列化,那么这就要提供一个接口/标识符,需要序列化的类要贴上标识符。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。这个标识符就是 Serializable 或 Externalizable(定制自己的序列化算法),实现了任何一个接口就代表可以被序列化。
java 有个工具可以查看一个类是否能够使用"java序列化",用法如下:
通过Serializable接口对对象序列化的支持是内建于核心api的,也就是说只要类实现java.io.Serializable接口,java就会试图存储和重组你的对象。如果使用外部化,程序员就可以自由地完成读取和存储的方式(自定义序列化算法、反序列化算法)。
## 知识点补充 (序列化接口)
在两者之间如何选择要根据应用程序的需求来定。serializable通常是最简单的解决方案,但是虚拟机必须弄清楚每个成员属性的结构,所以可能会导致不可接受的性能问题或空间问题;在出现这些问题的情况下,externalizable可能是一条可行之路。要记住一点,如果一个类是可外部化的(externalizable),那么externalizable方法将被用于序列化类的实例,即使这个类型也提供了serializable方法。
五、哪些东西需要序列化
类里那么多东西 ,哪些需要进行序列化?序列化的原则就是:序列化的信息要足够帮助我们在反序列化的时候恢复之前对象的状态就可以了,空间能省则省(毕竟涉及到网络传输问题)。那我们来分析下面这个Person.java类:
执行上面的main方法,可以看到如下结果:
对象序列化使用的是一种特殊的文件格式来存储对象。使用UltraEdit打开personbyte文件(上述案例生成),使用16进制的方式查看字节序列,如下:
无论是用什么权限标识符修饰(public/private/protected)的成员变量,他们都是对象的状态,不序列化成员变量的话,反序列化的实例也是不完整的。所以,普通成员变量必须序列化。
静态变量其实是类属性,并不属于某个具体实例,所以也不用保存。当恢复对象的时候,直接取类当前的静态变量即可。(可以放开Person类中的static int i=0;注释,执行结果不变同上图)
方法只是类的无状态指令。重建类的时候,可以直接从类的信息中获取,所以也不需要被序列化。(同样可以用代码验证)
以上讨论的都是很简单的情形,下面看一些复杂场景:
java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。
接口一般是无状态的,就算有也是static的,那么毫无疑问,接口的信息也不会被序列化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。