171130之Java序列化
来源:互联网 发布:刷黄金卷轴软件 编辑:程序博客网 时间:2024/06/05 16:47
Java序列化的作用
有的时候我们想要把一个Java对象变成字节流的形式传出去,有的时候我们想要从一个字节流中恢复一个Java对象。例如,有的时候我们想要把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流。
对于这种通用的操作,我们为什么不使用统一的格式呢?没错,这里就出现了java的序列化的概念。在Java的OutputStream类下面的子类ObjectOutputStream类就有对应的WriteObject(Object object) 其中要求对应的object实现了java的序列化的接口。
为了更好的理解java序列化的应用,我举两个自己在开发项目中遇到的例子:
1)在使用tomcat开发JavaEE相关项目的时候,我们关闭tomcat后,相应的session中的对象就存储在了硬盘上,如果我们想要在tomcat重启的时候能够从tomcat上面读取对应session中的内容,那么保存在session中的内容就必须实现相关的序列化操作。
2)如果我们使用的java对象要在分布式中使用或者在rmi远程调用的网络中使用的话,那么相关的对象必须实现java序列化接口。
Java对象的序列化有两种方式
a.是相应的对象实现了序列化接口Serializable,这个使用的比较多.
对于序列化接口Serializable接口是一个空的接口,它的主要作用就是标识这个对象时可序列化的,jre对象在传输对象的时候会进行相关的封装。
下面是一个实现序列化接口的Java序列化的例子:
public class Article implements java.io.Serializable { private static final long serialVersionUID = 1L; private Integer id; private String title; //文章标题 private String content; // 文章内容 private String faceIcon;//表情图标 private Date postTime; //文章发表的时间 private String ipAddr; //用户的ip private User author; //回复的用户
b.实现序列化的第二种方式为实现接口Externalizable
首先,我们在序列化对象的时候,由于这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性可以序列化,哪些不可以序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列的时候自动调用readExternal()方法,根据序列顺序挨个读取进行反序列,并自动封装成对象返回,然后在测试类接收,就完成了反序列。
所以说Exterinable的是Serializable的一个扩展.
对于实现Java的序列化接口需要注意一下几点:
1.java中的序列化时transient变量(这个关键字的作用就是告知JAVA我不可以被序列化)和静态变量不会被序列化(下面是一个测试的例子)
class Person implements Externalizable{ private static final long serialVersionUID = 1L; String userName; String password; String age; public Person(String userName, String password, String age) { super(); this.userName = userName; this.password = password; this.age = age; } public Person() { super(); } /** * 序列化操作的扩展类 */ @Override public void writeExternal(ObjectOutput out) throws IOException { //增加一个新的对象 Date date=new Date(); out.writeObject(userName); out.writeObject(password); out.writeObject(date); } /** * 反序列化的扩展类 */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { //注意这里的接受顺序是有限制的哦,否则的话会出错的 // 例如上面先write的是A对象的话,那么下面先接受的也一定是A对象... userName=(String) in.readObject(); password=(String) in.readObject(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); Date date=(Date)in.readObject(); System.out.println("反序列化后的日期为:"+sdf.format(date)); } @Override public String toString() { //注意这里的年龄是不会被序列化的,所以在反序列化的时候是读取不到数据的 return "用户名:"+userName+"密 码:"+password+"年龄:"+age; }}/** * 序列化和反序列化的相关操作类 */class Operate{ /** * 序列化方法 */ public void serializable(Person person) throws FileNotFoundException, IOException{ ObjectOutputStream outputStream=new ObjectOutputStream(new FileOutputStream("a.txt")); outputStream.writeObject(person); } /** * 反序列化的方法 */ public Person deSerializable() throws FileNotFoundException, IOException, ClassNotFoundException{ ObjectInputStream ois=new ObjectInputStream(new FileInputStream("a.txt")); return (Person) ois.readObject(); }}public class Test{ public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { Operate operate=new Operate(); Person person=new Person("小浩","123456","20"); System.out.println("为序列化之前的相关数据如下:\n"+person.toString()); operate.serializable(person); Person newPerson=operate.deSerializable(); System.out.println("-------------------------------------------------------"); System.out.println("序列化之后的相关数据如下:\n"+newPerson.toString()); }}
重点:
最应该注意的,如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象是先被序列化的对象,不要先接收对象B,那样会报错.尤其在使用上面的Externalizable的时候一定要注意读取的先后顺序。
实现序列化接口的对象并不强制声明唯一的serialVersionUID,是否声明serialVersionUID对于对象序列化的向上向下的兼容性有很大的影响。
转自博客:http://blog.csdn.net/u012554102/article/details/51902697
- 171130之Java序列化
- Java之序列化
- Java之序列化
- java之序列化
- java之序列化
- Java之序列化
- java之序列化
- Java之序列化
- JAVA之序列化
- Java序列化之自定义序列化
- java序列化之比较
- Java之序列化小记
- java序列化之serialVersionUID
- Java学习之序列化
- Netty之java序列化
- Java回顾之序列化
- java基础之序列化
- Java 进阶 之 序列化
- 让我编译一个程序(cpp)
- Hibernate环境搭建
- Bootstrap学习笔记 17
- android6.0/7.0 dump CallStack使用
- pyhton flask中调试模式的使用
- 171130之Java序列化
- Dima and Sequence CodeForces
- mysql 忘记 root 密码
- 2017/11/29C语言笔记整理
- (大整数) n 的阶乘 , n 的阶乘连续相加,和a(a为任何整数)的n次方
- Linux和unix中 awk 的print浅谈
- 05-方法values演示) 06-Map集合-常见子类对象) 07-Map集合-HashMap存储自定义对象) 08-Map集合-TreeMap存储自定义对象) 1 2
- C++学习笔记--类型转换函数
- 《大宇:Qt从入门到精通》目录