Why should I bother about serialVersionUID?

本文详细解释了Java中serialVersionUID的作用及重要性。它用于确保序列化的兼容性,避免因类版本不同导致的InvalidClassException异常。文章建议显式声明serialVersionUID,并介绍了如何维护其数值以保持序列化对象的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自: http://stackoverflow.com/questions/285793/why-should-i-bother-about-serialversionuid


The docs for java.io.Serializable are probably about as good an explanation as you'll get:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.


If you're actually using serialization, it only matters if you plan on storing and retrieving objects using serialization directly. The serialVersionUID represents your class version, and you should increment it if the current version of your class is not backwards compatible with its previous version.

Most of the time, you will probably not use serialization directly. If this is the case, generate a default serializable uid by clicking the quick fix option and don't worry about it.


If you will never need to serialize you're objects to byte array and send/store them, then you don't need to worry about it. If you do, then you must consider you're serialVersionUID since the deserializer of the object will match it to the version of object its classloader has. Read more about it in the Java Language Specifications.


The purpose of the serialization version UID is to keep track of different versions of a class in order to perform valid serialization of objects.

The idea is to generate an ID that is unique to a certain version of an class, which is then changed when there are new details added to the class, such as a new field, which would affect the structure of the serialized object.

Always using the same ID, such as 1L means that in the future, if the class definition is changed which causes changes to the structure of the serialized object, there will be a good chance that problems when trying to deserialize an object.

If the ID is omitted, Java will actually calculate the ID for you based on fields of the object, but I believe it is an expensive process, so providing one manually will improve performance.

Here's are a couple of links to articles which discuss serialization and versioning of classes:


The idea behind using 1L is so that you increment it every time you change the class properties or methods.

The main reason for the generated one would be to make it compatible with an existing version of the class that already has persisted copies.

The "long" default of the serialVersionUID is the default value as defined by theJava Serialization Specification, calculated from the default serialization behaviour.

So if you add the default version number, your class will (de-)serialize faster as long as nothing has structurally changed, but you'll have to take care that if you change the class (add/remove fields) you also update the serial number.

If you do not have to be compatible to existing bit streams, you can just put 1L there and increment the version as needed when something changes. That is, when the default serialisation version of the changed class would be different from the default version of the old class.

You absolutely should create a serialVersionUID every time you define a class that implementsjava.io.Serializable. If you don't, one will be created for you automatically, but this is bad. The auto-generated serialVersionUID is based on the method signatures of your class, so if you change your class in the future to add a method (for example), deserializing the "old" versions of the class will fail. Here's what can happen:

1. Create the first version of your class, without defining the 
serialVersionUID. 
2. Serialize an instance of your class to a persistent store; a 
serialVersionUID is automatically generated for you. 
3. Modify your class to add a new method, and redeploy your application. 
4. Attempt to deserialize the instance that was serialized in step 2, but now it fails (when it should succeed), because it has a 
different auto-generated serialVersionUID. 


U can use the serialver command line tool - at least in Sun's JDK to calculate theserialVersionUID for a given compiled class.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值