它把我难倒了从推出的Serializable
接口,为什么我必须纳入所有我的课的这个领域。 据我所知,这个接口需要一个唯一的标识符,以纪念类,但为什么他们不能产生这种在运行时。 例如,他们可以使用完全合格的类名称的MD5哈希或用于处理中出现次数很少重复类似的方法产生的呢(是的,我敢肯定,当被问及反正来生成ID是什么日食一样)。
所以我问什么(没有这个职位不仅是对标准库夸大其词)被序列化领域究竟是如何使用的框架?
我想之所以知道,因为我要尝试创建一个看点(AspectJ中或其他语言),将使用MD5哈希添加的serialVersionUID领域,能够处理的方式,是可以接受的API冲突。
我会后的结果,如果我能得到它的工作。
不要求具有serialVersionUID
领域。 如果你不提供一个,Java将根据领域和你的类的方法生成一个。
为什么你可能要注明原因serialVersionUID
是为了防止当方法改变,这不会影响串行二进制更改值。 考虑类:
public class Person implements Serializable {
private String name;
public String getName() {
return name;
}
}
没有serialVersionUID
指定。 如果您运行serialver Person
则返回:
Person: static final long serialVersionUID = 3793453319058452486L;
现在,您决定添加一个方法,但留下的字段相同。
public class Person implements Serializable {
private String name;
public String getName() {
return name;
}
public Object foo() {
return "bar";
}
}
序列化的二进制仍与老版本完全兼容,但serialVersionUID
是不同的:
Person: static final long serialVersionUID = -6188734029437600310L;
用不同serialVersionUID
,反序列化将导致serialVersionUID的失配误差。 解决方法是声明自己serialVersionUID
将其设置为任意值(我将它设置1L
),并改变它,每当领域发生了变化。
另见本相关的问题“什么是的serialVersionUID和我为什么要使用它呢?” 对于更详细的讨论。
为什么我要纳入所有我的课的这个领域
你不知道。
为什么他们不能产生这种在运行时
他们这样做,除非你自己提供。
我将尝试创建一个看点(AspectJ中或其他语言),将使用MD5哈希添加的serialVersionUID领域
这将是毫无意义的。 你don'understand就是它的功能。 在运行时产生的是什么已经默认情况发生,所以你的提议没有任何价值。 价值在于在编译时指定它,以便吸收实际上不破对象版本的兼容性较小的类发生变化。 你不能完成这个通过AOP。 这是一个编码的决定。
该Serializable
接口
这个接口存在于java.io
包中。 实现此方法来保护未成年变化和实施,以使用户能够write
并save
在运行时的对象。 该接口由所有Swing组件实现的,因为开发人员可以扩展他们,让JVM能找到的成分,即新版本, Your class
。
的serialVersionUID
该serialVersionUID
用作Serializable类版本控制。 如果你没有明确声明的serialVersionUID, JVM will did it for you automatically
,根据你的Serializable类的各个方面,如描述Java(TM) Object Serialization Specification
作为@Steve郭提到的,它不要求具备serialVersionUID
领域。
这是令人沮丧的,因为它不作为合同的一部分执行的对象是可序列化,大约有一半在我们的团队开发商去做,而另一半则没有。 那些通常只设置了广大private static final long serialVersionUID = 1L;
(虽然有些开发人员喜欢使用它作为一个机会,尝试他们的手在未来与伪多头...)
话虽如此,我始终明白它是在版本序列化对象一个初步的尝试。
比方说,我们有:
public class PersonDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String firstName;
private String lastName;
// Appropriate getters/setters of course
}
后来我们增加一个新的领域, private String middleInitial
。
如果我们到的serialVersionUID磕碰到2,我们可以用它来指示类已更改,并PersonDTO与年长的serialVersionUID已序列化实例不能与此修改类的定义反序列化。