当前位置:   article > 正文

粤嵌星计划打卡第四十天(javaString类和数组:引用数据类型的数组,二维数组定义使用 数组拷贝、Arrays类)(序列化梳理)(比较详细)_下面两种给引用数据类型的数组进行元素初始化的区别及原因 2020-11-25 10:30发布

下面两种给引用数据类型的数组进行元素初始化的区别及原因 2020-11-25 10:30发布

#粤嵌我来了##粤嵌星计划#
粤嵌星计划挑战
今天打卡第四十天
今天的学习内容java中io流部分中关于序列化的整理()

文章目录

一、为什么需要序列化?
二、反序列化时如何生成实例
三、是不是所有的类都需要序列化
四、java序列化(Serializable)和外部化(Externalizable)的主要区别
五、哪些东西需要序列化

  1. 普通成员变量需要序列化
  2. 静态变量无需序列化
  3. 方法无需序列化
  4. 属性是一个引用(需要被序列化)
    5.有父类(较为复杂)
  5. 有实现接口(接口内容无需序列化)
  6. 用transient保护的敏感信息不用序列化
    六、java序列化为什么要使用serialversionUID
    七、序列化应用
    1.dubbo RPC序列化
    2.缓存序列化
    3.各种序列化方式比较(kryo/fst/json/hessian2)
    八、参考链接:
    一、为什么需要序列化?
    java进程运行时会把相关的类生成一堆实例,并放入堆栈空间中,如果进程执行结束,那么内存中的实例对象就会被gc回收。如果想在新的程序中使用之前那个对象,应该怎么办?
    远程接口调用的时候,两端在各自的虚拟机中进行,因为内存不是共享的,那么入参和返回值该如何传递。
    序列话就是来解决这个问题的,虽然内存不是共享的,但是我们可以将对象转换为一段字节序列,并放到流中,接下来交给io流,可以存储到文件中,
    可以通过网络传输……当我们想用到这些对象的时候,再通过 I/O,从文件、网络上读取字节序列,根据这些信息重建对象。可以通过网络传输……当我们想用到这些对象的时候,再通过 I/O,从文件、网络上读取字节序列,根据这些信息重建对象
    用现实生活中的搬桌子为例,桌子太大了不能通过比较小的门,我们要把它拆了再运进去,这个拆桌子的过程就是序列化。同理,反序列化就是等我们需要用桌子的时候再把它组合起来,这个过程就是反序列化。
    在这里插入图片描述

二、反序列化时如何生成实例

:不用类去显示声明无参构造方法,而是通过一种语言之外的对象创建机制
 这里就有两个问题需要注意:
1。 通过序列化可以任意创建实例,不受任何限制。单例模式如果实现序列化的话,通过反序列化也可以轻松创建对象。
2. 由于不调用类自己的构造器,而是通过构造器Constructor来实现的。一些限制条件就很难满足。比如,有两个参数 max,min,构造时必须满足 max>min。如果不满足参数条件,系统存在被序列化攻击的风险。
3. 对象进行序列化时,类中所定义的被private、final等访问控制符所修饰的字段是直接忽略这些访问控制符而直接进行序列化的,因此,原本在本地定义的想要控制字段的访问权限的工作都是不起作用的。对于序列化后的有序字节流来说一切都是可见的,对象中的任何private字段几乎都是以明文的方式出现在套接字流中,这严重破坏了原有类的数据的“安全性”。幸运的是,我们可以让序列化的类可以实现一个 writeObject方法;反序列化过程,我们将在同一个类上实现一个readObject方法,通过使用writeObject 和 readObject 可以实现密码加密和签名管理
在这里插入图片描述
三、是不是所有的类都需要序列化
是不是所有的类都需要序列化? 如果是,则序列化就应该是类的基本功能,如果这样的话,序列化就应该对程序员彻底透明才是,所以并不是所有的类都需要序列化,原因如下:

	安全问题:有的类是**敏感的**类,里面的数据不能公开。而实现了序列化就很容易被破解,可以说没有秘密可言,隐私性没有保证。
		**资源问题**:序列化可以任意生成实例而不受限制,如果有的对象生成的实例是受限制的,比如只能生成10个实例,或者是单例的,这个很难保证。
		所以不是所有的类都需要序列化,那么这就要提供一个接口/标识符,需要序列化的类要贴上标识符。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。这个标识符就是 Serializable 或 Externalizable(定制自己的序列化算法),实现了任何一个接口就代表可以被序列化。
		java 有个工具可以查看一个类是否能够使用"java序列化",用法如下:
  • 1
  • 2
  • 3
  • 4

四、java序列化(Serializable)和外部化(Externalizable)的主要区别

通过Serializable接口对对象序列化的支持是内建于核心api的,也就是说只要类实现java.io.Serializable接口,java就会试图存储和重组你的对象。如果使用外部化,程序员就可以自由地完成读取和存储的方式(自定义序列化算法、反序列化算法)。
## 知识点补充 (序列化接口)
在这里插入图片描述
 在两者之间如何选择要根据应用程序的需求来定。serializable通常是最简单的解决方案,但是虚拟机必须弄清楚每个成员属性的结构,所以可能会导致不可接受的性能问题或空间问题;在出现这些问题的情况下,externalizable可能是一条可行之路。要记住一点,如果一个类是可外部化的(externalizable),那么externalizable方法将被用于序列化类的实例,即使这个类型也提供了serializable方法。
在这里插入图片描述
五、哪些东西需要序列化
类里那么多东西 ,哪些需要进行序列化?序列化的原则就是:序列化的信息要足够帮助我们在反序列化的时候恢复之前对象的状态就可以了,空间能省则省(毕竟涉及到网络传输问题)。那我们来分析下面这个Person.java类:
在这里插入图片描述
在这里插入图片描述执行上面的main方法,可以看到如下结果:
在这里插入图片描述
对象序列化使用的是一种特殊的文件格式来存储对象。使用UltraEdit打开personbyte文件(上述案例生成),使用16进制的方式查看字节序列,如下:在这里插入图片描述
在这里插入图片描述

1. 普通成员变量需要序列化

无论是用什么权限标识符修饰(public/private/protected)的成员变量,他们都是对象的状态,不序列化成员变量的话,反序列化的实例也是不完整的。所以,普通成员变量必须序列化。

2. 静态变量无需序列化

静态变量其实是类属性,并不属于某个具体实例,所以也不用保存。当恢复对象的时候,直接取类当前的静态变量即可。(可以放开Person类中的static int i=0;注释,执行结果不变同上图)

3. 方法无需序列化

方法只是类的无状态指令。重建类的时候,可以直接从类的信息中获取,所以也不需要被序列化。(同样可以用代码验证)
  以上讨论的都是很简单的情形,下面看一些复杂场景:

4. 属性是一个引用(需要被序列化)

在这里插入图片描述
在这里插入图片描述
java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。

6. 有实现接口(接口内容无需序列化)

接口一般是无状态的,就算有也是static的,那么毫无疑问,接口的信息也不会被序列化。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/68580
推荐阅读
  

闽ICP备14008679号