是否可以在运行时获取java类的serialVersionUID

问题描述 投票:0回答:4

众所周知,如果您未能显式定义它,运行时将为您的类生成serialVersionUID字段。

但是有可能在runitme中获得这个值吗?是否可以在运行时,参考.class获取它的serialVersionUID

java serialization
4个回答
26
投票
 Integer i = new Integer(5);
 long serialVersionID = ObjectStreamClass.lookup(i.getClass()).getSerialVersionUID();

以上是运行时获取类的序列号版本id的示例代码。


2
投票

当然可以。

serialVersionUID
是一个常规静态变量,因此您可以在需要时访问它。唯一的问题是它通常定义为
private
protected
,因此您只能从类本身访问它。要从外部访问它,您可以使用反射:

Class<?> clazz = obj.getClass();
Field f = clazz.getDeclraredField("serialVersionUID");
f.setAccessible(true);
long uid = (long)f.getValue();

2
投票

我想要的:当我更改这些类的内部结构时,强制我的代码自动更改

serialVersionUID

不,你不知道。您希望永远保持

serialVersionUID
不变,并将内部更改限制为序列化可以自动处理的内容,为此您需要查阅对象序列化规范的版本控制章节。每次阶级变化时改变
serialVersionUID
是一个都市神话,不幸的是它被广泛传播和接受。

您提出的解决方案也行不通。 “跳过[a]类旧版本的反序列化实例”并不是解决任何问题的方法。如果

serialVersionUIDs
不同意,序列化将已经拒绝它,但有例外。之后你做的任何事情都已经太晚了。

这听起来像是一个 XY 问题。你想做 X,你认为 Y 就是答案,所以当你应该问 X 时你却问 Y。正确的解决方案见上文。


0
投票

这里是关于 ObjectStreamClass#lookup 方法的 nullability已接受答案的稍微修改版本。

Optional.ofNullable(ObjectStreamClass.lookup(c))
        .map(ObjectStreamClass::getSerialVersionUID)
        .orElse(0L))
© www.soinside.com 2019 - 2024. All rights reserved.