有三种方法可以定义serialVersionUID:
1. private static final long serialVersionUID = 1L; (Default)
2. private static final long serialVersionUID = -8940196742313994740L; (Generated)
3. Don't define serialVersionUID and let the JVM define it at runtime. @Lance Java
Run Code Online (Sandbox Code Playgroud)
但我不明白第一种方式!
我已经看过了,有人为源代码中的所有java类定义了"serialVersionUID = 1L".
什么意思?这有用吗?
如果所有类都具有相同的serialVersionUID 1L,那么没有问题吗?
Mic*_*rdt 13
什么意思?这有用吗?
是.serialVersionUID的目的是让程序员控制哪个类的版本在序列化方面被认为是不兼容的.只要serialVersionUID保持不变,序列化机制将尽最大努力翻译序列化实例,这可能不是您想要的.如果进行语义更改以使旧版本不兼容,则可以更改serialVersionUID以使反序列化旧实例失败.
如果所有类都具有相同的serialVersionUID 1L,那么没有问题吗?
不 - serialVersionUID是每个类.
这在这里解释:
serialVersionUID是Serializable类的通用版本标识符.反序列化使用此数字来确保加载的类与序列化对象完全对应.如果未找到匹配项,则抛出InvalidClassException.
来自javadoc:
序列化运行时将每个可序列化类与版本号相关联,称为serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否已加载与该序列化兼容的该对象的类.如果接收者为具有与相应发送者类的serialVersionUID不同的对象加载了一个类,则反序列化将导致InvalidClassException.可序列化类可以通过声明名为"serialVersionUID"的字段来显式声明其自己的serialVersionUID,该字段必须是static,final和long类型:
有用的链接
InvalidClassException如果serialVersionUID序列化对象的序列化对象与serialVersionUID被反序列化的类不匹配,则JVM将抛出一个.
该serialVersionUID一类的应该改变每次以不兼容的方式改变类.通常这意味着每次更改shape类(即字段或方法更改).
在某些情况下,您不希望serialVersionUID更改.例如,您可以在应用程序中接受旧版本的对象.在这种情况下,您可以保留serialVersionUID相同的新字段并将其作为null.
是的,我看过代码也是这样定义的serialVersionUID.我认为这是一个坏主意.
在这种情况下,该serialVersionUID领域只有一个"显着"的价值; 即零... 0L.零表示" 根据您正在序列化/反序列化的实际类,通过应用标准算法在运行时计算版本ID ".这意味着只要代码的有效序列化签名发生更改,序列化/反序列化代码就会使用不同的版本ID.从(大图)类型的安全角度来看,这是最安全的事情,尽管它也有些低效,而且可能更脆弱.
什么意思?
在1L没有任何特殊含义.它只是一个1L与"其他"版本ID 匹配的数字.
在我看来,你最好使用0L或者使用标准算法(某些时候)生成的版本号.
如果使用0L,那么如果类以可能导致问题的方式发生变化,则会获得明确的反序列化异常.如果你需要这个,这是一件好事.
另一方面,您使用生成的版本ID,您(程序员)可以自己决定何时重新生成id.当您决定重新生成时,只有在类签名发生更改时,id才会更改.(如果类表示等没有改变,重新生成的签名应该与原始签名相同!)当id 确实改变时,你可以考虑是否添加自定义方法('readObject'等)来处理不兼容性.
但是,如果您使用1L,则无法判断版本ID是否需要在不检查代码历史记录的情况下进行更改,并且可以根据需要将类的旧版本/新版本进行比较.
这有用吗?
这取决于你认为"有用"的意思.如果您认为将版本ID硬连接到"相信我,它没问题"是一件好事,那么1L它很有用.
我的回忆是,某些版本的Eclipse提供1L了一个可能的自动更正,用于丢失serialVersionUID字段警告.这可能是你看到的实例来自哪里.
想象一下你用a编写一个类serialVersionUID,实例化它,然后将其序列化为一个文件(使用ObjectOutputStream)
然后你修改类.
然后,使用修改后的类,反序列化(读入)修改前序列化的版本.Java将检查serialVersionUID当前类和序列化类的类型,如果它们不匹配,则反序列化将失败.这是一个故意的快速失败,以防止由于类版本不兼容而导致稍后发生的更微妙(并且更难调试)错误.
如果省略serialVersionUID则禁用版本检查.如果始终将if设置为1L,则检查将始终通过(值始终相同),因此您仍然容易受到细微的类版本不兼容问题的影响.
您可以long为 分配任何值serialVersionUID,但每次修改类时都必须更改它。
第二个看起来像是serialVersionUID基于当前类版本的功能生成的。