《编写高质量代码:改善Java程序的151个建议》 建议11

11. 养成良好习惯,显示声明UID

Serial Version ID也叫流标识符(Stream Unique Identifier),即类的版本定义,它可以现实声明也可以隐式声明。显示声明格式如下:

private static final long serialVersionUID = XXXXXL;
而隐式声明则是由编译器在编译的时候帮助生成。生成的依据是通过包名、类名、继承关系、非私有的方法和属性,以及参数、返回值等诸多因子计算得出的,基本上计算出来的这个值是唯一的。

serialVersionUID的作用:JVM 在反序列化时,会比较数据流中的serialVersionUID与类的serialVersionUID是否相同,如果相同,则认为类没有发生改变,可以把数据流 load 为实例对象;如果不同,则会抛出InvalidClassException异常

这是一个非常好的校验机制,可以保证一个对象即使在网络或磁盘中“滚过”一次,仍能做到“出淤泥而不染”,完美地实现类的一致性。

但是如果我们的类改变不大,希望能实现向上兼容,这时就需要向JVM撒谎,也就是依靠显式声明相同的 serialVersionUID

通过这种向上兼容,无疑提高了代码的健壮性,并且我们在编写序列化类代码时,随手加上serialVersionUID字段也不会给我们带来太多的工作量,但它却可以在关键时候发挥异乎寻常的作用。

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


示例:

数据对象Person:

V1.0版本:

public class Person implements Serializable {
	private static final long serialVersionUID = 55799L;
	private String name;
	/* 省略 name 属性的 getter/setter 方法 */
}

V2.0版本:

public class Person implements Serializable{
	private static final long serialVersionUID = 55799L;
	private String name;
	private int age;
        /* 其他保持不变 */
}

序列化工具类:

public class SerializationUtils {
	private static String FILE_NAME = "c:/obj.bin";

	// 序列化
	public static void writeObject(Serializable s) {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream(FILE_NAME));
			oos.writeObject(s);
			oos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 反序列化
	public static Object readObject() {
		Object obj = null;
		try {
			ObjectInput input = new ObjectInputStream(new FileInputStream(
					FILE_NAME));
			obj = input.readObject();
			input.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
}
// 生产者
public class Producer {
	public static void main(String[] args) {
		Person person = new Person();
		person.setName("Michael");
	}
}
// 消费者
public class Consumer {
	public static void main(String[] args) {
		Person person = (Person) SerializationUtils.readObject();
		System.out.println("name = " + person.getName());
	}
}
这样一来V2.0版本的Person类即能兼容V1.0版本。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值