java序列化和反序列化

JAVA序列化和反序列化的方式主要有两种:


1.实现Serializable接口:

相应的对象实现了序列化接口Serializable,这个使用的比较多,对于序列化接口Serializable接口是一个空的接口,它的主要作用就是标识这个对象时可序列化的,jre对象在传输对象的时候会进行相关的封装


2.实现Externalizable接口:

Externalizable接口继承了Serializable接口,并增加了两个方法

void writeExternal(ObjectOutput out) throws IOException;

        void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

      首先,我们在序列化对象的时候,由于这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性可以序列化,哪些不可以序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列的时候自动调

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

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


 
import  java.io.Externalizable;
import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectInput;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutput;
import  java.io.ObjectOutputStream;
import  java.text.SimpleDateFormat;
import  java.util.Date;
 
 
/**
  * 测试实体类
  */
class  Person  implements  Externalizable{
         private  static  final  long  serialVersionUID = 1L;<br>    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 ();
     }
 
 
     public  String getAge() {
         return  age;
     }
     public  void  setAge(String age) {
         this .age = age;
     }
     public  String getUserName() {
         return  userName;
     }
     public  void  setUserName(String userName) {
         this .userName = userName;
     }
     public  String getPassword() {
         return  password;
     }
     public  void  setPassword(String password) {
         this .password = password;
     }
     
     /**
      * 序列化操作的扩展类
      */
     @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{
     /**
      * 序列化方法
      * @throws IOException
      * @throws FileNotFoundException
      */
     public  void  serializable(Person person)  throws  FileNotFoundException, IOException{
         ObjectOutputStream outputStream= new  ObjectOutputStream( new  FileOutputStream( "a.txt" ));
         outputStream.writeObject(person);      
     }
     
     /**
      * 反序列化的方法
      * @throws IOException
      * @throws FileNotFoundException
      * @throws ClassNotFoundException
      */
     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());
     }
     
     
}

注意问题:

1.对于不想序列化的字段可以使用transient声明。使用transient声明的字段不参与序列化。

2.serialVersionUID必不可少。没有serialVersionUID时,序列化时会根据字段和特性的算法生成一个serialVersionUID,但是当对象的属性(增加或者减少字段)发生变化时,serialVersionUID会发生变化,则反序列化失败.


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值