努力的小胖学习记录(七)-------Java序列化

  • 什么是java系列化?
    为了对象能够在网络间传输(如rpc,rmi等),将对象转换为二进制流的过程称为序列化。同样的,将二进制流转换为对象的过程称为反序列化。
  • Java系列化的几种方法?
  1. 实现Serializable接口
    这是大家最常见的一种也是最简单的一种方式,该接口没有任何方法,实现了该接口的对象可以直接使用ObjectOutputSteam的writeObject方法写到流里面,然后调用ObjectInputStream的readObject方法将其读出来。这里因为大家都知道也熟悉,我就不贴代码了,主要看下面两种方式。
  2. 实现Externalizable接口
    首先我们看下该接口的结构
    Externalizable接口结构
    这个接口里面方法,方别对应的是写对象到流的writeExternal和从流中读对象的readExternal方法,这个相比直接Serializable实现而言,这里可以控制更多的细节,比如你可以将一个transient字段也保存起来。下面看代码
package com.hxw.serialize;

import java.io.*;

public class ExternalizableDemo implements Externalizable{
    private char value ;
    private transient int count ;
    public ExternalizableDemo(char value,int count){
        System.out.println("ExternalizableDemo External Constructor");
        this.value = value;
        this.count = count;
    }
    public ExternalizableDemo(){
        System.out.println("ExternalizableDemo Default Constructor");
    }

    @Override
    public String toString() {
        return "ExternalizableDemo{" +
                "value=" + value +
                ", count=" + count +
                '}';
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        System.out.println("write object");
        out.writeObject(value);
        out.writeObject(count);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        System.out.println("read object");
        this.value = (char)in.readObject();
        this.count = (int)in.readObject();
    }
    public static void test() throws Exception{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SeriallizeTest.FILE));
        oos.writeObject(new ExternalizableDemo('a',1));
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(SeriallizeTest.FILE));
        Object obj = ois.readObject();
        System.out.println(obj);
    }
}

这里有两点需要大家注意
2.1第一种和下面的第三种方式读对象的时候是都不会调用构造器,而这种方式会调用构造器,所以必须要要有一个默认的构造器
2.2读和写的顺序必须要一致,否则会出现前后值对不上的问题,第三种同样存在

  1. 实现Serializable接口并增加writeObject和readObject方法
    注意,这里是增加不是覆盖。直接看代码
package com.hxw.serialize;

import java.io.*;

public class SerialExtend implements Serializable{
    private  String a;
    private  String d;
    private  transient  String b;
    private  transient  String c;
    public SerialExtend(String a, String b, String c, String d) {
        System.out.println("construct");
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
    public SerialExtend() {
        System.out.println("default construct");
    }
    private  void writeObject(ObjectOutputStream out) throws Exception{
        out.defaultWriteObject();
        out.writeObject(b);
        out.writeObject(c);
    }
    private  void readObject(ObjectInputStream in)throws Exception{
        in.defaultReadObject();
        b = (String)in.readObject();
        c = (String)in.readObject();
    }

    @Override
    public String toString() {
        return "SerialExtend{" +
                "a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }
    public static void test() throws Exception{
        SerialExtend sc = new SerialExtend("test1","test2","test3","test4");
        System.out.println("before:" + sc);
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(buf);
        o.writeObject(sc);
        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buf.toByteArray()));
        SerialExtend sc2 = (SerialExtend) in.readObject();
        System.out.println("after:"+sc2);
    }
}

这个方式其实和第二种方式有点类似的,都可以控制细节,并且也会产生顺序问题,而且defalutRead和defaultWrite(自动处理非transient字段)也可以换成我们的普通read和write同样也能完成工作。这里和第二点不同的就是这里不会调用构造器。

  • 扩展点
  1. 对象写进文件后的内容
    主要看AscII
    其实认真看ASCII码,虽然有点乱码,但是不能猜出其实它存的就是对象的信息,包括属于哪个类,每个字段的值等(个人猜测,还未验证)
  2. 同一对象使用同一输入流调用两次write后,后面读两次的话,读的对象也是同一个,可以用上面的额随便一个demo测试同一对象使用同一输入流调用两次write后,后面读两次的话,读的对象也是同一个,可以用上面的随便一个demo测试
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值