反序列化

来源:互联网 发布:淘宝账户冻结怎么解冻 编辑:程序博客网 时间:2024/03/29 08:42

 

(1)serialVersionUID 用来表明类的不同版本间的兼容性。Java的序列化机制是在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 当实现Serializable接口的类没有显式地定义一个名为serialVersionUID的时候,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID 。 如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,未作更改的类,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。
(2)在java中serialVersionUID是唯一控制着能否反序列化成功的标志,  只要这个值不一样,就无法反序列化成功。

序列化就是 保存在内存中的各种对象的状态(也就是实例变量,不是方法),之后在某个地方可以把保存的对象状态再还原回来。

一般在你想把的内存中的对象状态保存到一个文件中的时候、用套接字在网络上传送对象的时候、当你想通过RMI传输对象的时候才好用到这个东西。

序列化的对象要实现 java.io.Serializable。
给你举个例子。

想要序列化的对象:
Class 名是:Own,实现了java.io.Serializable


Java code
package com.test.serialization;public class Own implements java.io.Serializable{private int no = 272;private String name = "bzwm";private String sex = "man";public String getName(){return name;}public void setName(String name){this.name = name;}public int getNo(){return no;}public void setNo(int no){this.no = no;}public String getSex(){return sex;}public void setSex(String sex){this.sex = sex;}}



然后用Class SaveReadOwn 来保存对象,再把它读出来。
Java code
package com.test.serialization;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class SaveReadOwn{public static void main(String args[]){ SaveReadOwn s = new SaveReadOwn(); Own myself = new Own(); myself.setNo(272); myself.setName("HIBZWM"); myself.setSex("man"); // change my name s.save(myself); myself.setName("other"); System.out.println("change myname to : " + myself.getName()); //read object myself = (Own)s.read("foo.ser"); System.out.println("saved object : myName = " + myself.getName());}// savepublic void save(Own foo){ try { FileOutputStream fos = new FileOutputStream("foo.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(foo); fos.close(); } catch(Exception e) { e.printStackTrace(); }}//readpublic Object read(String objPath){ Object foo = null; try { FileInputStream fis = new FileInputStream(objPath); ObjectInputStream ois = new ObjectInputStream(fis); foo = ois.readObject(); ois.close(); fis.close(); } catch(Exception e) { e.printStackTrace(); } return foo;}}


运行结果自己看吧。

 
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP

  • bzwm用户头像
  • bzwm
  • (在哪里跌倒,就在哪里躺下。)
  • 等 级:
#5楼 得分:5回复于:2009-01-07 12:22:40
接着我修改这两个类。

首先 SaveReadOwn 类我不做save 处理,我只想把 “楼上的代码” 里保存的对象反序列化回来。
代码如下:

Java code
package com.test.serialization;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class SaveReadOwn{public static void main(String args[]){ SaveReadOwn s = new SaveReadOwn(); Own myself = null;//new Own(); // myself.setNo(272);// myself.setName("HIBZWM");// myself.setSex("man"); // change my name// s.save(myself);// myself.setName("other");// System.out.println("change myname to : " + myself.getName()); //read object myself = (Own)s.read("foo.ser"); System.out.println("saved object : myName = " + myself.getName());}// savepublic void save(Own foo){ try { FileOutputStream fos = new FileOutputStream("foo.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(foo); fos.close(); } catch(Exception e) { e.printStackTrace(); }}//readpublic Object read(String objPath){ Object foo = null; try { FileInputStream fis = new FileInputStream(objPath); ObjectInputStream ois = new ObjectInputStream(fis); foo = ois.readObject(); ois.close(); fis.close(); } catch(Exception e) { e.printStackTrace(); } return foo;}}

此时我只修改了 用来读取对象的类,然后执行,结果你自己试试。

接着,我把类 Own 修改一下,加一个字段 private final int test = 0;
Java code
package com.test.serialization;public class Own implements java.io.Serializable{private int no = 272;private String name = "bzwm";private String sex = "man";private final int test = 0;public String getName(){ return name;}public void setName(String name){ this.name = name;}public int getNo(){ return no;}public void setNo(int no){ this.no = no;}public String getSex(){ return sex;}public void setSex(String sex){ this.sex = sex;}}


然后你再执行一下,就会报错了。
类似 这样的信息:
java.io.InvalidClassException: com.test.serialization.Own; local class incompatible: stream classdesc serialVersionUID = 7794841109938881749, local class serialVersionUID = 6646693911615467598


继续修改类 Own,加一个字段:private static final long serialVersionUID = 7794841109938881749l;(强制修改uid)


Java code
package com.test.serialization;public class Own implements java.io.Serializable{private int no = 272;private String name = "bzwm";private String sex = "man";private final int test = 0;private static final long serialVersionUID = 7794841109938881749l;public String getName(){return name;}public void setName(String name){this.name = name;}public int getNo(){return no;}public void setNo(int no){this.no = no;}public String getSex(){return sex;}public void setSex(String sex){this.sex = sex;}}


再执行,看结果吧。

原创粉丝点击