序列化过程:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,
当反序列化时系统会去检测文件中的serialVersionUID,
判断它是否与当前类的serialVersionUID一致,
如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。
serialVersionUID有两种显示的生成方式:
一是默认的1L,比如:private static final long serialVersionUID = 1L;
二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
private static final long serialVersionUID = xxxxL;
1 当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,
Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,
这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),
就算再编译多次,serialVersionUID也不会变化的。
2 如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,
就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。
当两次序列化的版本号serialVersionUID不一致时,会导致:
[Java] 纯文本查看 复制代码
?
1
Exception in thread "main" java.io.InvalidClassException: com.demo.seriDemo.DataObject; local class incompatible: stream classdesc serialVersionUID = 1175939230834636559, local class serialVersionUID = -7343438723219659897
注意:
(1)静态成员是不能被序列化的,因为静态成员是随着类的加载而加载的,与类共存亡,并且静态成员的默认初始值都是0;
能被序列化的只是某个对象的成员.
(2)如果同时在一次代码执行中进行序列化和反序列化,此时类中的静态成员是有值的,并不是因为静态的成员
能够被序列化,而是此次运行jvm保存了静态成员。所以会发现好像静态成员被序列化和反序列化一样。
代码如下:
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public static void main(String[] args) throws Exception {
// 序列化DataObject对象
Serialize();
// 反序列DataObject对象
DataObject object = Deserialize();
// 静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已,
// 这里的不能序列化的意思,是序列化信息中不包含这个静态成员域,下面
// 之所以i输出还是2,是因为测试都在同一个机器(而且是同一个进程),因为这个jvm
// 已经把i加载进来了,所以获取的是加载好的i,如果是传到另一台机器或者关掉程序重新
// 写个程序读入DataObject.txt,此时因为别的机器或新的进程是重新加载i的,所以i信息就是初始时的信息,即0
System.out.println(object);
}
/**
* MethodName: SerializePerson
* Description: 序列化对象
* @author
* @throws FileNotFoundException
* @throws IOException
*/
private static void Serialize() throws FileNotFoundException, IOException {
DataObject object = new DataObject();
object.setName("张三");
object.setAge(10);
// 创建ObjectOutputStream对象输出流,其中用到了文件的描述符对象和文件输出流对象
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
new File("DataObject.txt")));
// 将DataObject对象存储到DataObject.txt文件中,完成对DataObject对象的序列化操作
oo.writeObject(object);
System.out.println("对象序列化成功!");
// 最后一定记得关闭对象描述符!!!
oo.close();
}
/**
* MethodName: DeserializePerson
* Description: 反序列DataObject对象
* @author
* @return
* @throws Exception
* @throws IOException
*/
private static DataObject Deserialize() throws Exception, IOException {
// 创建ObjectInputStream对象输入流,其中用到了文件的描述符对象和文件输入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
new File("DataObject.txt")));
// 从DataObject.txt文件中读取DataObject对象,完成对DataObject对象的反序列化操作
DataObject object = (DataObject) ois.readObject();
System.out.println("对象反序列化成功!");
// 最后一定记得关闭对象描述符!!!
ois.close();
return object;
}
推荐阅读
Python 反序列化安全问题(二)
代码结构可以分为:基础变量、自定义异常类、操作变量、序列化以及反序列化类以及普通函数。代码(28-57行)最先定义了部分变量,如最高协议号还有代码中使用了struct.pack()以及marshal.loads()进行序列化和反序列化,并且解释了为何用这两个函数。代码(59-85行)中自定义了4个异常类,分别为PickleError、PicklingError、UnpicklingError以及_
1fe1se 阅读 19
Bitcoin序列化库使用
Bitcoin序列化功能主要实现在serialize.h文件,整个代码主要是围绕stream和参与序列化反序列化的类型T展开。 stream这个模板形参表达具有read(char**,size_t)和write(char**,size_t)方法的对象,类似Golang的io.reader,io.writer。简单的使用例子:需要在用户的自定义类型内部添加ADD_SERIALIZE_METHODS调
姜家志 阅读 1
序列化与json性能评测
日常工作中需要在数据库中存储一些结构数据,常用的方法有两种,一是序列化(serialize),二是json格式。两者各有优缺点,比如序列化支持对象格式、序列化后的数据会保存数据类型和数据个数。而json格式相比序列化的数据更短,并且前后端交互时适用性也更好。但在实际的项目中,应该用哪种格式来存储数据呢?网上说法不一,老手们更倾向于序列化(可能是因为json格式是在PHP5.2之后才引进的),而年轻
kphcdr 阅读 26
JAVA 序列化
原文https:www.ibm.comdeveloper...将Java对象序列化为二进制文件的Java序列化技术是Java系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现Serializable接口,使用ObjectInputStream和ObjectOutputStream进行对象的读写。然而在有些情况下,光知道这些还远远不够,文章列举了笔者遇到的一些真实
曾纪文 阅读 2
Java ---- 序列化
Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装
燃烧你的梦 阅读 12
序列化一个Intent
版权声明:本公众号发布的所有文章,均属于原创,版权归本公众号所有。允许有条件转载,转载请附带底部二维码。在Android中,打开一个Activity,有多少种方式?不过不管是使用什么方式,最终都没办法逃避创建一个Intent,然后startActivity。那么,如果想根据数据来确定跳转的页面呢?需要怎么做比较好一点。DeepLink好像是一个不错的解决方案,在AndroidManifest.xm
plokmju88 阅读 1
由JSON序列化失败引起的对序列化过程配置的思考
本次遇到问题时所使用的框架是SpringBoot,处理完请求之后,返回数据之前,在POJO转化成JSON时,有些属性违背输出规则或者有些属性循环引用会造成无法输出。报错信息:org.springframework.http.converter.HttpMessageNotWritableException:CouldnotwriteJSON:Noserializerfoundforclassjav
小栋20 阅读 1
Java大数据内存序列化浅谈(一)
谈任何技术前,不讨论实际的应用场景都是耍流氓。首先说下自身项目背景。业务只读不写,且数据量不大,这两个特性很大程度上决定了我们的系统架构。Step0数据平台持久化数据到数据库(SQLServer)中,然后压缩数据库文件成压缩文件Step1上传压缩文件到云端,利用云端进行自动同步Step2通知各个节点下载数据,下载到指定目录Step3解压文件,附加数据库文件为新库Step4节点读取新数据库数据到内存
defcon 阅读 2