【编程思想】03 编写高质量代码、Java 开发中通用的方法和准则

11、养成良好习惯,显式声明UID

  1. 介绍

a: 类实现Serializable接口的目的是为了可持久化,比如网络传输或本地存储,为系统的分布和异构部署提供先决支持条件。

b:JVM在反序列化时,会比较数据流中的serialVersionUID与类的serialVersionUID是否相同,如果相同,则认为类没有发生改变,可以把数据流load为实例对象;如果不相同,对不起,我JVM不干了,抛个异常InvalidClassException给你瞧瞧。这是一个非常好的校验机制,可以保证一个对象即使在网络或磁盘中“滚过”一次,仍能做到“出淤泥而不染”,完美地实现类的一致性。

c: 反序列化实现了版本向上兼容的功能,使用V1.0版本的应用访问了一个V2.0版本的对象,这无疑提高了代码的健壮性。我们在编写序列化类代码时,随手加上serialVersionUID字段,也不会给我们带来太多的工作量,但它却可以在关键时候发挥异乎寻常的作用。

d: 显式声明serialVersionUID可以避免对象不一致,但尽量不要以这种方式向JVM“撒谎”。

  1. 被序列化类
package com.hao.test.Serialization;

import lombok.Data;

import java.io.Serializable;

/**
 * @author haoxiansheng
 */
@Data
public class Person implements Serializable {
    private static final long seriaVersionUID=2610414093143345504L;
    private String name;

    //private Integer age;
}

  1. 生产者
package com.hao.test.Serialization;

/**
 * @author haoxiansheng
 */
public class Producer {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("zhangsan");
        //person.setAge(99);
        // 序列化保存到磁盘
        SerializationUtils.writeObject(person);
    }
}

  1. 消费者
package com.hao.test.Serialization;

import lombok.extern.slf4j.Slf4j;

/**
 * @author haoxiansheng
 */
@Slf4j
public class Consumer {
    public static void main(String[] args) {
        // 反序列化
        Person p = (Person)SerializationUtils.readObject();
        log.info("p=>{}",p);
    }
}

  1. 序列化工具类
package com.hao.test.Serialization;

import java.io.*;

/**
 * @author haoxiansheng
 */
public class SerializationUtils {
    private static String FILE_NAME = "/Users/haoxiansheng/Downloads/Spring-Family/flameboy/src/main/resources/doc/obj.bin";

    // 序列化
    public static void writeObject(Serializable serializable) {
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
            outputStream.writeObject(serializable);
            outputStream.close();
        } catch (IOException e) {

        }
    }

    public static Object readObject() {
        Object object = null;
        // 反序列化
        try {
            ObjectInput input = new ObjectInputStream(new FileInputStream(FILE_NAME));
            object = input.readObject();
            input.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
}

你可能感兴趣的:(【编程思想】)