欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-04 08:27:10
...

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;
    }
}

相关标签: 编程思想