博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java序列化
阅读量:6437 次
发布时间:2019-06-23

本文共 3205 字,大约阅读时间需要 10 分钟。

hot3.png

##简介 java序列化与反序列化相当简单,实现serializable接口即可.序列化和反序列化主要用于不同系统的之间的通信,可以让对象以流的形式进行传输,一个系统接受之后,然后反序列化成对象,获取相应的属性,完成相应的动作.然java内部的实现,可能会消耗很多内存.

###谨慎实现序列化

实现uid,使用IDE自己生成的UID(序列化版本号);

注意读取的安全,因为程序可能会访问正在构造中的对象;

需注意相应的序列化版本不兼容问题;

内部类不需要实现序列化,

如果不是专门用于序列化的实体类,不要实现序列化接口.

###考虑使用自定义的序列化形式

1.避免类导出的API束缚在该类的内部表示法上,提高扩展性;

2.避免消耗过多的时间和空间

3.避免引起栈溢出

####如何自定义序列化方法

private void writeObject(ObjectOutputStream s )throws IOException{    s.defaultWriteObject();    //其他输出内部字段的代码}private void readObject(ObjectInputStream s){    s.defaultReadObject();    //其他读取内部字段的代码}

默认的序列化方法会序列化并输出每个非transient域;默认的反序列化方法会读取并转化每个非transient域.

对于transient域,请自定义其输出和读取;

###保护性编写readObject方法

  • readObject()方法可以认为是一个以字节流作为唯一参数的构造器.

  • 你必须为你的readObject()方法提供保护性拷贝和有效性检查.

  • 对于非final的类,readObject()方法不应该调用其非final方法,因为重写可能会导致失败;

  • 可以使用ObjectInputValidation接口对反序列化之后的类进行验证.

###使用序列化代理来替代序列化实例

当你必须在一个不能被客户端扩展的并带有约束条件的类上编写readObject或writeObject方法时,就必须考虑使用序列化代理模式.

序列化代理,在目标类外建立一个私有静态嵌套类,

package com.wangge.serialize;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InvalidObjectException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.io.Serializable;import java.util.Date;public class Period implements Serializable {  private static final long serialVersionUID = -2072208249014270392L;  private final Date start;  private final Date end;    public Period(Date start, Date end) {    super();    this.start = new Date(start.getTime());    this.end = new Date(end.getTime());  }    public Date getStart() {    return new Date(this.start.getTime());  }    public Date getEnd() {    return new Date(this.end.getTime());  }    private Object writeReplace() {    return new SerializationProxy(this);  }    private void readObject(ObjectInputStream stream) throws InvalidObjectException {    throw new InvalidObjectException("Proxy required");  }    @Override  public String toString() {    return "Period [start=" + start + ", end=" + end + "]";  }    private static class SerializationProxy implements Serializable {    private static final long serialVersionUID = -2072208249014270314L;    private final Date start;    private final Date end;        SerializationProxy(Period p) {      this.start = p.start;      this.end = p.end;    }        private Object readResolve() {      return new Period(start, end);    }  }    public static void main(String[] args) {    try {      ByteArrayOutputStream bos = new ByteArrayOutputStream();      ObjectOutputStream out = new ObjectOutputStream(bos);      out.writeObject(new Period(new Date(), new Date()));            byte[] ref = { 0x71, 0, 0x70, 0, 5 };      bos.write(ref);      ref[4] = 4;      bos.write(ref);      ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));      Object period = in.readObject();      System.out.println(period);      Object ob = in.read();      System.out.println(ob);    } catch (IOException e) {      e.printStackTrace();    } catch (ClassNotFoundException e) {      e.printStackTrace();    }      }}

缺点:1.不能被客户端扩展的类兼容,不能在序列化中被调用;2.会降低性能.

转载于:https://my.oschina.net/u/1590027/blog/809075

你可能感兴趣的文章
编译安装PHP
查看>>
css position:static 的使用
查看>>
nfs永久挂载与临时挂载
查看>>
linux查看网络链接状况命令之-netstat
查看>>
我的友情链接
查看>>
UIView的layoutSubviews和drawRect方法何时调用
查看>>
mysql主从同步
查看>>
制作最简化的Linux系统
查看>>
我的友情链接
查看>>
使用List的remove方法需要的注意的问题
查看>>
Ansible的介绍、安装、配置及常用模块介绍
查看>>
编码列表
查看>>
eigrp 配置
查看>>
谈一谈 redis 集群
查看>>
concurrent包
查看>>
在Linux下调试Python代码的各种方法
查看>>
centos7塔建MQ服务器
查看>>
Peer authentication failed for user
查看>>
超强的.NET图像工具包VintaSoftImaging.NET SDK更新至v8.6丨75折优惠
查看>>
阿里云上Kubernetes集群联邦
查看>>