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();
    }
}
总结:
- 当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
- 当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
- 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;
        }
    }
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号