- 浏览: 485235 次
- 性别:
- 来自: 长沙
文章分类
最新评论
-
Source_野驴:
...
jsp静态化和伪静态化 -
zidanzzg:
很好的知识,找到了利用异或交换数值的理论支持,谢谢分享
XOR的性质和运算 -
ueseu:
引用(2) DomainDomain域名也是Cookie的一部 ...
Cookie的组成 -
ueseu:
引用Secure取true或者false值。如果为true,那 ...
Cookie的组成 -
liqi___123:
理解得很透彻,谢谢!!
ROLAP、MOLAP和HOLAP联机分析处理区别
先来看一个例子:
定义一个bean:
序列化操作:
反序列化操作:
运行程序,则反序列化成功。
现在改动一下bean,在定义的bean中添加一个公有方法(非私有就可以):
接下来在老版本的序列化的结果上反序列化就会出错:
接下来在定义的bean中显示的声明UID,如下:
再次重新执行上面的步骤,则反序列化成功。
有时候你的类增加了一些无关紧要的非私有方法,而逻辑字段并不改变的时候,你希望老版本和新版本保持兼容性,则需要显式的声名UID来实现。
以下内容来自网络:
====================================================================
如何保持向上兼容性:
向上兼容性是指老的版本能够读取新的版本序列化的数据流。常常出现在我们的服务器的数据更新了,仍然希望老的客户端能够支持反序列化新的数据流,直到其更新到新的版本。可以说,这是半自动的事情。
跟一般的讲,因为在java中serialVersionUID是唯一控制着能否反序列化成功的标志,只要这个值不一样,就无法反序列化成功。但只要这个值相同,无论如何都将反序列化,在这个过程中,对于向上兼容性,新数据流中的多余的内容将会被忽略;对于向下兼容性而言,旧的数据流中所包含的所有内容都将会被恢复,新版本的类中没有涉及到的部分将保持默认值。利用这一特性,可以说,只要我们认为的保持serialVersionUID不变,向上兼容性是自动实现的。
当然,一但我们将新版本中的老的内容拿掉,情况就不同了,即使UID保持不变,会引发异常。正是因为这一点,我们要牢记一个类一旦实现了序列化又要保持向上下兼容性,就不可以随随便便的修改了!!!
测试也证明了这一点,有兴趣的读者可以自己试一试。
如何保持向下兼容性:
一如上文所指出的,你会想当然的认为只要保持serialVersionUID不变,向下兼容性是自动实现的。但实际上,向下兼容要复杂一些。这是因为,我们必须要对那些没有初始化的字段负责。要保证它们能被使用。
所以必须要利用
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException{
in.defaultReadObject();//先反序列化对象
if(ver=5552){//以前的版本5552
…初始化其他字段
}else if(ver=5550){//以前的版本5550
…初始化其他字段
}else{//太老的版本不支持
throw new InvalidClassException();
}
}
细心的读者会注意到要保证in.defaultReadObject();能够顺利执行,就必须要求serialVersionUID保持一致,所以这里的ver不能够利用serialVersionUID了。这里的ver是一个我们预先安插好的final long ver=xxxx;并且它不能够被transient修饰。所以保持向下的兼容性至少有三点要求:
1.serialVersionUID保持一致
2.预先安插好我们自己的版本识别标志的final long ver=xxxx;
3.保证初始化所有的域
讨论一下兼容性策略:
到这里我们可以看到要保持向下的兼容性很麻烦。而且随着版本数目的增加。维护会变得困难而繁琐。讨论什么样的程序应该使用怎么样的兼容性序列化策略已经超出本文的范畴,但是对于一个游戏的存盘功能,和对于一个字处理软件的文档的兼容性的要求肯定不同。对于rpg游戏的存盘功能,一般要求能够保持向下兼容,这里如果使用java序列化的方法,则可根据以上分析的三点进行准备。对于这样的情况使用对象序列化方法还是可以应付的。对于一个字处理软件的文档的兼容性要求颇高,一般情况下的策略都是要求良好的向下兼容性,和尽可能的向上兼容性。则一般不会使用对象序列化技术,一个精心设计的文档结构,更能解决问题。
发表评论
-
java String.getBytes()编码问题 (讲到实处了)
2012-12-12 11:26 796转载自: String.getBytes()的问 ... -
JSP中文验证码
2012-05-14 17:18 1244以上两篇文章的内容介绍了有关JSP中产生数字验证码跟中文验证 ... -
One-Jar之旅
2011-09-16 10:06 1765One-Jar之旅 1 ... -
Javamail中的常见中文乱码问题与解决办法
2011-09-09 09:48 1656在使用javamail api开发邮件服务系统时,我们常常会碰 ... -
理解Java ClassLoader机制
2011-07-28 11:24 1387再次阅读这篇文章时,有了更深的体会,特转载之。 理解Ja ... -
JAVA泛型简介
2011-07-22 13:41 1235另篇:http://www.java3z.com/cwbweb ... -
BCEL和Javassist的介绍
2011-07-18 10:49 1607BCEL 介绍: Byte Code E ... -
类加载器特技:OSGi代码生成
2011-07-18 10:08 800转自:http://www.oschina.n ... -
开源的java编译器jikes
2011-06-19 08:50 2247今天才知道java编译器还有个jikes这样的开源产品。 ... -
java的沙盒机制
2011-01-28 18:03 2047JAVA 的安全模型不同于传统的安全方法,传统的安全方法中 ... -
filter的调用顺序
2011-01-06 11:54 1290在一个大型项目中往往有多个servlet过滤器,但是这些ser ... -
JAVA操作COOKIE
2010-12-28 11:32 12741.设置Cookie Cookie cookie = ... -
关于volatile变量的理解
2010-12-12 13:21 1004前些日子在看些多线 ... -
关于Java 构造函数和继续特性的回顾
2010-12-06 09:21 1200java构造函数 java类库的设计者们通过提供 ... -
Java可变参数方法重载的错误3例
2010-12-05 23:28 1123JDK1.5引进了方法的可变参数,受到许多开发人员的青睐。 ... -
JDK1.5新特性
2010-12-05 23:19 720"JDK1.5"的一个重要主题就是 ... -
Java 语言的 XPath API
2010-12-02 15:31 958如果要告诉别人买一加仑牛奶,您会怎么说?“请去买一加仑牛 ... -
java -verbose命令
2010-09-23 15:00 9399java -verbose[:class|gc|jni ... -
db2的jdbc驱动
2010-09-20 18:34 1275type1:jdbc-odbc桥 ... -
Java代码编写的30条建议
2010-07-21 23:28 6641) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母应 ...
相关推荐
Java 序列化和 serialVersionUID 的使用方法实例 Java 序列化是指将 Java 对象转换为二进制流的过程,以便在网络中传输或持久化到数据库或文件系统中。序列化的作用是将 Java 对象的状态保存起来,以便下次使用时...
Java对象的序列化和反序列化是Java编程中一项重要的技术,主要用于将对象的状态转换为字节流,以便存储或在网络上传输。这一过程对于理解Java的IO操作、持久化数据以及实现分布式通信等场景非常关键。 首先,我们来...
在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体(类)的 serialVersionUID 进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 在 ...
下面是一个简单的序列化示例代码,展示了如何将一个`Box`对象序列化并存储到文件中,然后再从文件中读取出来: ```java package com.hotye.dchaoxiong.serializabletest; import java.io.FileInputStream; import ...
序列化版本号serialVersionUID的作用_动力节点Java学院整理.
- Java允许使用 `writeObject()` 和 `readObject()` 方法来自定义序列化和反序列化的行为,这两个方法需要在类中声明为`private`,并由`java.io.Serializable` 接口的实现类提供。 7. **序列化安全性** - 序列化...
在给定的链接"Java序列化机制(2)- serialVersionUID 实验"中,博主通过一个实验详细解释了`serialVersionUID`的作用和重要性。实验可能包括以下步骤: 1. 创建一个实现`Serializable`接口的简单类,并运行序列化...
2. **如何实现反序列化**:使用`ObjectInputStream`的`readObject()`方法从流中读取对象: ```java try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myfile.ser"))) { MyObject obj = ...
序列化与反序列化是计算机科学中的重要概念,特别是在数据存储、网络通信和持久化对象等领域。简单来说,序列化是将对象的状态转换为可存储或传输的数据格式的过程,而反序列化则是将这种数据格式恢复为原来的对象...
也就是说,当我们序列化一个对象时,serialVersionUID 会被保存下来,并在反序列化时被用来检查对象的版本是否相同。 那么,serialVersionUID 有两种生成方式:一种是默认的 1L,例如:private static final long ...
1. **版本控制**:当类的结构发生变化时,`serialVersionUID`会发生变化,这样可以避免由于类的结构变化导致的序列化和反序列化过程中的不一致。 2. **兼容性检测**:在进行序列化和反序列化操作时,系统会比较序列...
Java序列化是Java平台中的一种持久化机制,它允许对象的状态被转换成字节流,以便存储、网络传输或在不同时间点恢复。这个过程被称为序列化,而反向操作称为反序列化。序列化在许多场景下都非常有用,比如在分布式...
- 使用`ObjectInputStream`的`readObject()`方法读取序列化的字节流,会根据字节流中的信息创建和初始化对象。 3. **潜在问题**: - 安全风险:恶意构造的序列化数据可能导致代码执行,因此在反序列化时要确保...
1. **文件保存**:当需要将内存中的对象状态保存到文件中或数据库中时,序列化非常有用。 2. **网络通信**:在网络上传输对象时,序列化能够将对象转换为字节流形式,便于在网络间传输。 3. **远程方法调用(RMI)**:...
为了避免这个问题,可以使用版本ID(serialVersionUID)来确保序列化兼容性。 ```java // 在类定义中添加版本ID private static final long serialVersionUID = 1L; ``` 文件的序列化和反序列化操作对于数据持久化...
在序列化过程中,可以使用反射机制来访问类的可序列化字段。这允许`ObjectOutputStream`和`ObjectInputStream`类动态地处理不同类型的对象。 **1.8 `ObjectOutput`接口** `ObjectOutput`接口定义了将对象序列化的...
在Java编程语言中,对象的序列化和反序列化是两个关键的概念,它们允许我们将对象的状态转换为可存储或传输的格式,然后再恢复为原始对象。这个过程对于数据持久化、网络传输以及跨进程通信等场景非常有用。下面将...
- 使用`ObjectInputStream`类的`readObject()`方法从文件中反序列化对象。例如: ```java FileInputStream fis = new FileInputStream("object.ser"); ObjectInputStream ois = new ObjectInputStream(fis); My...
在实际应用中,我们还可以使用`transient`关键字来标记那些不需要序列化的字段,因为这些字段可能包含敏感信息或者不应该被持久化的状态。同时,`volatile`字段在序列化和反序列化过程中可能会失去其特性,因此需要...