您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>源码下载>java源码下载>

java序列化的几种方式

大小:0.4 MB 人气: 2017-09-27 需要积分:1

  一.Java序列化的作用

  有的时候我们想要把一个Java对象变成字节流的形式传出去,有的时候我们想要从一个字节流中恢复一个Java对象。例如,有的时候我们想要

  把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流。对于这种通用

  的操作,我们为什么不使用统一的格式呢?没错,这里就出现了java的序列化的概念。在Java的OutputStream类下面的子类ObjectOutput-

  Stream类就有对应的WriteObject(Object object) 其中要求对应的object实现了java的序列化的接口

  为了更好的理解java序列化的应用,我举两个自己在开发项目中遇到的例子:

  1)在使用tomcat开发JavaEE相关项目的时候,我们关闭tomcat后,相应的session中的对象就存储在了硬盘上,如果我们想要在tomcat重启的

  时候能够从tomcat上面读取对应session中的内容,那么保存在session中的内容就必须实现相关的序列化操作。

  2)如果我们使用的java对象要在分布式中使用或者在rmi远程调用的网络中使用的话,那么相关的对象必须实现java序列化接口。

  亲爱的小伙伴,大概你已经了解了java序列化相关的作用,接下来们来看看如何实现java的序列化吧。~

  二。实现java对象的序列化和反序列化。

  Java对象的序列化有两种方式。

  a.是相应的对象实现了序列化接口Serializable,这个使用的比较多,对于序列化接口Serializable接口是一个空的接口,它的主要作用就是

  标识这个对象时可序列化的,jre对象在传输对象的时候会进行相关的封装。这里就不做过多的介绍了。

  下面是一个实现序列化接口的Java序列化的例子:非常简单

  packagecom.shop.domain; importjava.util.Date;publicclassArticleimplementsjava.io.Serializable{privatestaticfinallongserialVersionUID =1L; privateInteger id; privateString title; //文章标题privateString content; // 文章内容privateString faceIcon; //表情图标privateDate postTime; //文章发表的时间privateString ipAddr; //用户的ipprivateUser author; //回复的用户publicInteger getId() { returnid; }publicvoidsetId(Integer id) { this.id = id; } publicString getTitle() { returntitle; }publicvoidsetTitle(String title) { this.title = title; } publicString getContent() { returncontent; }publicvoidsetContent(String content) { this.content = content; } publicString getFaceIcon() {returnfaceIcon; } publicvoidsetFaceIcon(String faceIcon) { this.faceIcon = faceIcon; }publicDate getPostTime() { returnpostTime; } publicvoidsetPostTime(Date postTime) {this.postTime = postTime; } publicUser getAuthor() { returnauthor; }publicvoidsetAuthor(User author) { this.author = author; } publicString getIpAddr() {returnipAddr; } publicvoidsetIpAddr(String ipAddr) { this.ipAddr = ipAddr; } }

  b.实现序列化的第二种方式为实现接口Externalizable,Externlizable的部分源代码如下:

  * @seejava.io.ObjectInput * @seejava.io.Serializable * @sinceJDK1 .1*/publicinterfaceExternalizableextendsjava.io.Serializable{/** * The object implements the writeExternal method to save its contents * by calling the methods of DataOutput for its primitive values or

  没错,Externlizable接口继承了java的序列化接口,并增加了两个方法:

  - void writeExternal(ObjectOutput out) throws IOException; - void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

  首先,我们在序列化对象的时候,由于这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性可以序列化,

  哪些不可以序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列的时候自动调

  用readExternal()方法,根据序列顺序挨个读取进行反序列,并自动封装成对象返回,然后在测试类接收,就完成了反序列。

  所以说Exterinable的是Serializable的一个扩展。

  为了更好的理解相关内容,请看下面的例子:

  packagecom.xiaohao.test; importjava.io.Externalizable; importjava.io.FileInputStream;importjava.io.FileNotFoundException; importjava.io.FileOutputStream;importjava.io.IOException; importjava.io.ObjectInput; importjava.io.ObjectInputStream;importjava.io.ObjectOutput; importjava.io.ObjectOutputStream;importjava.text.SimpleDateFormat; importjava.util.Date; /** * 测试实体类 *@author小浩 * @创建日期 2015-3-12 */class Person implements Externalizable{privatestaticfinallongserialVersionUID = 1L;《br》 String userName; String password; String age; publicPerson(String userName, String password, String age) { super();this.userName = userName; this.password = password; this.age = age; } publicPerson() {super(); } publicString getAge() { returnage; } publicvoidsetAge(String age) { this.age = age; } publicString getUserName() { returnuserName; } publicvoidsetUserName(String userName) { this.userName = userName; } publicString getPassword() { returnpassword; }publicvoidsetPassword(String password) { this.password = password; } /** * 序列化操作的扩展类 */@OverridepublicvoidwriteExternal(ObjectOutput out) throwsIOException { //增加一个新的对象Date date= newDate(); out.writeObject(userName); out.writeObject(password); out.writeObject(date); } /** * 反序列化的扩展类 */@OverridepublicvoidreadExternal(ObjectInput in) throwsIOException, ClassNotFoundException { //注意这里的接受顺序是有限制的哦,否则的话会出错的// 例如上面先write的是A对象的话,那么下面先接受的也一定是A对象。。.userName=(String) in.readObject(); password=(String) in.readObject(); SimpleDateFormat sdf=newSimpleDateFormat( “yyyy-MM-dd”); Date date=(Date)in.readObject(); System.out.println( “反序列化后的日期为:”+sdf.format(date)); } @OverridepublicStringtoString() { //注意这里的年龄是不会被序列化的,所以在反序列化的时候是读取不到数据的return“用户名:”+userName+ “密 码:”+password+ “年龄:”+age; } } /** * 序列化和反序列化的相关操作类 *@author小浩 * @创建日期 2015-3-12 Java学习交流QQ群:589809992 我们一起学Java! */class Operate{ /** * 序列化方法 *@throwsIOException *@throwsFileNotFoundException */publicvoidserializable(Person person)throwsFileNotFoundException, IOException{ ObjectOutputStream outputStream=newObjectOutputStream( newFileOutputStream( “a.txt”)); outputStream.writeObject(person); } /** * 反序列化的方法 *@throwsIOException *@throwsFileNotFoundException *@throwsClassNotFoundException */publicPersondeSerializable() throwsFileNotFoundException, IOException, ClassNotFoundException{ ObjectInputStream ois= newObjectInputStream( newFileInputStream( “a.txt”));return(Person) ois.readObject(); } } /** * 测试实体主类 *@author小浩 * @创建日期 2015-3-12 */publicclassTest{publicstaticvoidmain(String[] args) throwsFileNotFoundException, IOException, ClassNotFoundException { Operate operate= newOperate(); Person person= newPerson( “小浩”, “123456”, “20”); System.out.println( “为序列化之前的相关数据如下:\n”+person.toString()); operate.serializable(person); Person newPerson=operate.deSerializable(); System.out.println( “-------------------------------------------------------”); System.out.println( “序列化之后的相关数据如下:\n”+newPerson.toString()); } }

  首先,我们在序列化UserInfo对象的时候,由于这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性可

  以序列化,哪些不可以序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列

  的时候自动调用readExternal()方法,根据序列顺序挨个读取进行反序列,并自动封装成对象返回,然后在测试类接收,就完成了反

  序列。

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!