Java 对象的序列化


一.对象序列化的作用

我们都知道Java是一门面向对象的语言,自然很多地方,都要有这种思想,网络传输数据,或者保存到磁盘文件中,是否可以以直接保存或则传输一个对象,数据都封装在对象里面(这样可以大大减少我们传输数据的操作),答案是一定的,对象的序列化就提供这样的作用。

二. 怎么实现序列化

对象序列化:把对象转换成字节流的过程 。
反序列化:从字节流中重构一个对象的过程。
让一个对象成为可序列化的,必须要该对象实现Serializable标记接口。默认的序列化处理过程是序列化对象中所有不是transient 和static的字段。这个Name类可以由writeObject直接写入ObjectOutputStream流里面去,name和id可以被写进去,而hash,hashset,nextId不能写入流中。通常,在我们转换成字节流,系统会为该类同时写入一个64位的serialVersionUID一个ID唯一标识这个类,一般我们最好手动标注,如果将来改动一下类,这个ID就会改变,反序列化就读取这个UID,就会不一致,出错抛出 InvalidClassException异常,我们应该标注出来(该UID必须为静态final字段而且是private),最好调出刚开始系统匹配出的UID值,就用他

ObjectStreamClass osc2 = ObjectStreamClass.lookup(Name.class);
      // 获取到SerialVersionUID的值
      System.out.println("" + osc2.getSerialVersionUID());
   public class Name implements java.io.Serializable{
      private static final long  serialVersionUID=-1307795172754062330L;
      private String name;
      private long id;
      private transient int hash;
      private transient boolean hashSet=false;
      private static long nextID=0;
      public Name(String name){
          this.name=name;     
 }
}
//通过流写入
ObjectOutputStream out=new ObjectOutputStream(in)//(进行流链接);
out.writeObject(name);//name是一个对象

怎么定制序列化?

有时候,我们不需要什么数据都写进去或则想要写入静态变量,这个时候就要重写writeObject()和readObject()

 public class BeterName implements Serializable{
 private static final long    serialVersionUID=-1307795172754062330L;
    private String name;
    private long id;
    private static long nextId=0;
    public BeterName(String name,long id){
     this.name=name;
     this.id=id;    
}
   private void writeObject(ObjectOutputStream out){
   throws IOException{
        out.writeUTF(name);
        out.writeLong(id);//这里可以控制转换成字节流里面的数据
        }
   }
private void readObject(ObjectInputStream in){
   throws IOException{
         name=in.readUTF();
         id=in.readLong();//和writeObject相对应
        }
  }
}

下面是一个实际运用:

//  StoreNode.java文件
import java.io.Serializable;

import org.omg.PortableInterceptor.IORInterceptor;

public class StoreNode  implements Serializable{
        private String ip;
        public static String name="data";
        private transient int hash;
        public StoreNode(String ip){
            this.ip=ip;
        }
        public String getIp(){
            return ip;
        }
        public String getName(){
            return name;
        }
}

// main执行文件
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import main.StoreNode;
public class main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
      File file = new File("Data.txt");
      StoreNode node = new StoreNode("192.0.0.1");
      node.name="Hello World";
      try {
      if(file.exists()){
            file.createNewFile();
      }
      FileOutputStream fileOutputStream = new FileOutputStream(file);
      ObjectOutputStream outputStream=new ObjectOutputStream(fileOutputStream);
      outputStream.writeObject(node);
      System.out.println("写入成功");
      outputStream.close();
      FileInputStream inputStream=new FileInputStream(file);
      ObjectInputStream stream = new ObjectInputStream(inputStream);
      StoreNode node2 = (StoreNode)stream.readObject();
      System.out.println("node 2 读出来的ip地址为: "+node2.getIp()+"\t node 2读出来的name: "+ node2.getName());
      stream.close();
      } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }
}

执行结果
这里写图片描述
(解释一下: 如果直接运行这个文件 name=’Hello world’ 你会以为name这个属性写进去去了,因为测试都在同一个机器(而且是同一个进程),因为这个jvm已经把name加载进来了,所以获取的是加载好的name),这时候要想获得正确结果,可以先执行写入文件,写入到data.txt中,然后关闭Eclipse,再执行readObject部分就会发现结果不一样)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值