shiro反序列化原理(反序列化是什么意思)
本文目录
- 反序列化是什么意思
- java resolve
- 什么是对象序列化(Serialization)和反序列化(Deserialization)
- java里为什么反系列化能调用私有属性和方法
- 什么是java序列化,如何实现java序列化
反序列化是什么意思
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
java resolve
java resolve是什么?让我们一起来了解一下吧! 原理: 反序列化时,首先获取序列化的类 : desc( 可理解为单例类的class类,但它和JVM加载到内存中的单例class类有不同)因为如果我们的单例类在构造方法中通过实例不为空则抛出异常防止了反射破坏单例,那单例类是不允许再实例化的。而desc类却依然可以实例化。(当我们反序列化一个对象时,永远不会调用其类的构造函数,反序列化后的实例变量与序列化之前的实例变量相同,类变量与当前的类变量相同,如果反序列化时类未被加载则类变量为默认值。) 判断对象是否能实例化。可以则进行实例化,至此单例类进行了第一次实例化,对象名为obj。第一次实例化完成后,通过反射寻找该单例类中的readResolve()方法,没有则直接返回obj对象。有定义readResolve()方法,desc通过invokeReadResolve(Object obj)方法调用readResolve()方法获取单例对象instance,将他赋值给rep,如果单例对象之前已经被实例化过,那么rep就会指向之前实例化的单例对象。如果我们之前没有实例化单例对象,则rep会指向null。 rep与obj进行比较,由于obj是反射获取的对象,当然与rep不等,于是将rep的值instance赋值给obj,将obj返回,返回对象instance也就保证了单例。java resolve是从序列化中恢复一个单例对象会破坏单例模式,解决方法是添加readResolve() :通过反序列化readObject()方法获取对象时会去寻找readResolve()方法,如果该方法不存在则直接返回新对象,如果该方法存在则按该方法的内容返回对象,以确保如果我们之前实例化了单例对象,就返回该对象。如果我们之前没有实例化单例对象,则会返回null。 实战演练,具体步骤如下所示: package com.singleton; import java.io.ObjectStreamException; import java.io.Serializable; /** * 懒汉单例设计模式案例 */ public class SingletonDemo implements Serializable { /** * 懒加载 */ private static SingletonDemo instance; /** * 私有构造器 */ private SingletonDemo() { // 防止通过反射实例对象而跳过getInstance()方法 if (instance != null) { throw new RuntimeException("Object has been Instance !!!"); } } /** * 调用方法才加载类,资源利用率高了,但要保证线程安全 */ public static synchronized SingletonDemo getInstance() { if (instance == null) { instance = new SingletonDemo(); } return instance; } /** * 提供readResolve()方法 * 当JVM反序列化恢复一个新对象时,系统会自动调用readResolve()方法返回指定好的对象 * 从而保证系统通过反序列化机制不会产生多的Java对象 * * @return 单例对象 * @throws ObjectStreamException 异常 */ private Object readResolve() throws ObjectStreamException { return instance; } } package com.singleton; import org.junit.Test; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * 单例测试类 */ public class SingletonTest { /** * 测试方法 */ @Test public void test() throws Exception { // 获取instance对象 SingletonDemo instance = SingletonDemo.getInstance(); // 获取文件输出流 FileOutputStream fileOutputStream = new FileOutputStream("E:\\Test.txt"); // 获取对象输出流 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); // 输出对象 objectOutputStream.writeObject(instance); // 关闭资源 objectOutputStream.close(); fileOutputStream.close(); // 获取对象输入流 ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\Test.txt")); // 读取对象 Object object = objectInputStream.readObject(); // 判断两个对象是否相等,返回true/false System.out.println(instance == object); } }
什么是对象序列化(Serialization)和反序列化(Deserialization)
【答案】:Java提供了一种叫做对象序列化的机制,他把对象表示成一连串的字节,里面包含了对象的数据,对象的类型信息,对象内部的数据的类型信息等等。因此,序列化可以看成是为了把对象存储在磁盘上或者是从磁盘上读出来并重建对象而把对象扁平化的一种方式。反序列化是把对象从扁平状态转化成活动对象的相反的步骤。
java里为什么反系列化能调用私有属性和方法
序列化可以将内存中的类写入文件或数据库中。比如将某个类序列化后存为文件,下次读取时只需将文件中的数据反序列化就可以将原先的类还原到内存中。也可以将类序列化为流数据进行传输。总的来说就是将一个已经实例化的类转成文件存储,下次需要实例化的时候只要反序列化即可将类实例化到内存中并保留序列化时类中的所有变量和状态。看了这个解释你应该明白了吧,序列化就是把实例化过的对象保存起来,反序列化就是把这个对象再拿出来用,因此你所谓的调用私有方法应该是调用该对象自身类的私有方法
什么是java序列化,如何实现java序列化
在java中只要一个类实现了Serializable接口的类就被认为是序列化的类,这种类的对象就是序列化的对象只有被序列化的数据才允许被存储到文件、数据库之中或者通过网络协议进行传输,没有被序列化的数据是不能存储到硬盘上,不能通过网络协议进行网络传输
更多文章:
java instanceof(java 编程instanceof 操作符)
2024年7月30日 03:40
clipboardproxy插件怎么安装(怎么安装插件,装到哪里)
2024年8月15日 03:55
switch的相关短语用法(switch语句怎么用啊 具体)
2024年7月2日 05:52
if if else怎么执行(在c语言程序中if-else语句的else语句总是不执行是怎么回事)
2024年7月22日 08:47
cstring数组定义(MFC如何定义CString类型的数组)
2024年7月19日 09:24
sqlserver备份表语句(SQLSERVER2005如何备份部分表中的部分数据)
2024年8月3日 16:25
web前端开发就业(学web前端好找工作吗 就业方向有哪些)
2024年7月23日 10:59
access2007教程(数据库应用Access2007实例教程的内容简介)
2024年5月2日 14:07
dreamweavercs6官网下载(求给个dreamweaver cs6 下载地址)
2023年7月25日 17:00