反序列化

 

(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()); } // save public 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(); } } // read public 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; } }


运行结果自己看吧。

 

  • 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()); } // save public 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(); } } // read public 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; } }


再执行,看结果吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值