java序列化

一. 序列化

把对象持久化,能够进行网络间的进程间通信。
非transient的进行序列化。
序列化的类需要实现Serializable或者Externalizable接口
序列化是先创建ObjectOutputStream,然后调用outputStream.writeObject(person)把对象写入到输出流中,反序列化是创建ObjectInputStream,然后调用ObjectInputStream的(Person)readObject()方法把对象读入到内存中,因为在person的定义中,已经存在Serializable或Externalnalizable定义的序列化和反序列化方法,所以能够对对象进行序列化和反序列化。
测试代码如下:

	 public void test() throws IOException, ClassNotFoundException {
	    Person person = new Person("z", 10, "man");
	    ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("a.txt"));
	    outputStream.writeObject(person);
	    ObjectInputStream ois=new ObjectInputStream(new FileInputStream("a.txt"));
	    Person newPerson = (Person) ois.readObject();
	    log.info("new Person : {}", newPerson);
	 }

1.1 实现了Serializable

1.2 实现Externalnalizable接口,同时实现writeExternal和readExternal

需要具备默认构造函数

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Slf4j
public class Person implements Externalizable {
    private static final long serialVersionUID = -3108730319469628306L;
    private String name;
    private int age;
    private String sex;

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        log.info("开始序列化");
        out.writeObject(name);
        out.writeObject(age);
        out.writeObject(sex);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        log.info("开始反序列化");
        this.name = (String)in.readObject();
        this.age = (int)in.readObject();
        this.sex = (String)in.readObject();
    }
}

总结:

  1. 当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
  2. 当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
  3. static,transient后的变量不能被序列化;不过,这是对默认Serializable而言的,对于Externalnalizable不存在默认的序列化方法,因此static和transient的内容依然可以通过手动序列化的方式进行。

1.3 serialVersionUID

serialVersionUID是根据类名,接口名,方法和属性等来生成的。
通过serialVersionUID可以控制序列化与反序列化结果的兼容性。
1、 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
2、 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

未生成无serialVersionUID警告,这个时候需要配置
setting->Inspections->Serialization issues中:
将serialzable class without "serialVersionUID"和Non-serialzable class with "serialVersionUID"
选上,确定。配置好后,选中类名,按atl+enter键,就可以自动生成serialVersionUID了。

二. ObjectOutputStream和ObjectInputStream

OutputStream类的子类ObjectOutputStream具有writeObject方法如下

public final void writeObject(Object obj) throws IOException {
        if (enableOverride) {
            writeObjectOverride(obj);
            return;
        }
        try {
            writeObject0(obj, false);
        } catch (IOException ex) {
            if (depth == 0) {
                writeFatalException(ex);
            }
            throw ex;
        }
    }
posted @ 2016-08-02 01:03  zhangshihai1232  阅读(203)  评论(0)    收藏  举报