IntelliJ IDEA生成serialVersionUID


297

如何在IntelliJ IDEA中生成此值?

我转到设置 -> 错误 -> 序列化问题 ->没有'serialVersionUID'的可序列化类,但是它仍然没有显示警告。我的类PKladrBuilding父类实现了Serializable接口

部分代码:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable

3
您确定需要生成一个值,而不是定义自己的值吗?如果要创建一个新类,我建议您定义例如1LID,并在序列化表格更改时递增。(请参阅stackoverflow.com/questions/888335/…)。
邓肯·琼斯

1
stackoverflow.com/questions/24573643/…有一个很好的解决方案。
Pankaj Kumar

Answers:


588

我不确定您是否具有IntelliJ IDEA的旧版本,但是如果我转到菜单文件设置...检查序列化问题 →未启用'serialVersionUID'的可序列化类,则您提供的类会给我警告。

在此处输入图片说明

如果我尝试第一堂课,我会看到:

在此处输入图片说明

顺便说一句:在我添加{ }到每个类的末尾以修复编译错误之前,它没有向我显示警告。


2
尝试File| Invalidate Caches,如果没有帮助,请通过示例项目与support@jetbrains.com联系,以进行复制。
CrazyCoder 2012年

1
检查idea.log(帮助|显示登录...)是否存在异常,已知Linux上的加密主目录会由于内核错误而引起问题。
CrazyCoder 2012年

1
我那里有很多例外。例如java.lang.NoClassDefFoundError:org / intellij / lang / annotations / MagicConstant;
Kirill Bazarov

2
我已经重新安装了IDEA并删除了插件,它对我有帮助。Tnx很多。
Kirill Bazarov

5
我在v15中使用它的方法是将鼠标悬停在ClassName上以查看警告,并将鼠标缓慢移向装订线。此时,“灯泡”显示在屏幕上。(如果第一次无法按预期方式尝试,请尝试几次)。然后,您可以单击创建字段选项来创建uid。希望这对那些坚持下去的人有所帮助。
Niyaz

173

安装Olivier Descout 的GenerateSerialVersionUID插件。

转到:菜单文件设置插件浏览存储库GenerateSerialVersionUID

安装插件并重新启动。

现在,您可以从菜单代码生成 →serialVersionUID`或快捷方式生成 ID 。


14
为了真正做到这一点,应该真的需要一个外部插件吗?
H.Rabiee 2014年

是的,您需要一个已经是IntelliJ插件存储库一部分的插件。
Sileria

为我工作了Intellij IDEA 12.1
Sagar Hatekar 2014年

适用于13.0.2。
user1978019 2014年

适用于Android Studio 0.8.9
Itai Hanski 2014年

67

没有任何插件:您只需要在IntelliJ中启用突出显示:

IntelliJ Preferences -> Editor -> Inspections -> Java -> Serialization issues -> Serializable class without 'serialVersionUID'-设置标志,然后单击'OK'

现在,如果您的班级实施了Serializable,您将看到突出显示,并alt+Enter在班级名称上建议生成private static final long serialVersionUID

PS:取自这里


4
谢谢。我不知道为什么看不到灯泡,但是单击类名并键入Alt-Enter可以解决问题。
约翰S



39

在序列化上花了一些时间后,我发现我们不应该serialVersionUID使用某个随机值生成,而应该给它一个有意义的值。

这是对此的详细评论。我在这里处理评论。

实际上,您不应该“生成”串行版本UID。这是一个愚蠢的“功能”,源于对Java如何使用该ID的普遍误解。您应该为这些ID提供有意义的,可读的值,例如,以1L开头,并在每次您认为该类的新版本应使所有先前的版本(可能先前已序列化)过时时递增它们。当未定义ID时,所有生成此类ID的实用程序基本上都会执行JVM的工作:它们会基于类文件的内容生成值,因此会产生无法理解的无意义的长整数。如果您希望类的每个版本都是不同的(在JVM看来),那么您甚至不应该指定serialVersionUID值,因为JVM会即时生成一个版本,并且您课程的每个版本的价值都是唯一的。显式定义该值的目的是告诉序列化机制将具有相同SVUID的类的不同版本视为相同,例如,不拒绝较旧的序列化版本。因此,如果您定义ID且从不更改它(并且我假设这是您所做的,因为您依赖自动生成,并且您可能永远不会重新生成ID),那么您将确保所有版本-甚至是完全不同的版本您的类将被序列化机制视为相同。那是你要的吗?如果不是这样,并且如果您确实想控制对象的识别方式,则应使用您自己可以理解的简单值,并在决定类已发生重大变化时轻松进行更新。

希望这可以帮助。祝好运。


2
谢谢,我跳过这个简单的事实已有很长时间了!
dedek

1
serialVersionUID当我不想在反序列化上支持旧版本时,实际上我会用新的随机数重新生成。也许我不需要使用随机数,但可以从1开始并递增。但是,那3L对我没有更多的意义-3518231192373568183L。因此,我猜这两种解决方案都可以类似地工作。但是,随机数可能具有以下优点:它会在具有分支和分支的非线性历史记录中苏醒。
JojOatXGME

16

为了产生价值使用

private static final long serialVersionUID = $randomLong$L;
$END$

并为randomLong模板变量提供以下值:groovyScript(“ new Random()。nextLong()。abs()”)

https://pharsfalvi.wordpress.com/2015/03/18/adding-serialversionuid-in-idea/


1
喜欢这个评论,可以使用实时模板,这肯定是最快的解决方案,并且是最可定制的(例如,我删除了换行符)。要进行配置,请转到Android Studio>“偏好设置”>“编辑器”>“实时模板”,然后在其中使用此值创建一个新的(加号图标),并使用编辑变量输入脚本
hcpl

13

另外,您可以添加将完成工作的实时模板。

为此,请按Ctrl+Alt+S-> "Live Templates"部分-> other(或您希望的w / e)

然后使用如下定义创建一个新的:

private static final long serialVersionUID = 1L;
$END$

然后选择definition范围并将其另存为'serial'

现在您可以输入serialTAB班级正文。


3

生成serialVersionUID的另一种方法是>Analyze >Run Inspection by Name从上下文菜单中使用(或键盘快捷键,默认情况下为ctrl+ alt+ shift+ i),然后键入“不带有'serialVersionUID'的Serializable类”(或直接键入“ serialVersionUID”和前面的类型)功能将为您找到它。

想法>分析>按名称运行检查 然后,您将获得一个上下文菜单,您可以在其中选择运行检查的位置(例如,全部来自特定模块,整个项目,一个文件,...)

使用这种方法,您甚至不必将常规检查规则设置为任何内容。


很好,这为我做了工作。它找到了丢失的变量,并提出了添加它的选项。
arenaq

@arenaq很高兴,这对其他人有所帮助;-)
亚历山大

2

带版本 v2018.2.1

首选项>编辑器>检查> Java>序列化问题>切换“无'serialVersionUID'的可序列化类”。

在类声明旁边应出现警告。


1

我使用的是Android Studio 2.1,通过单击类Name并将其悬停一秒钟,可以更好地获得灯泡。


1

将一个名为“ ser”的活动模板添加到另一个组,将其设置为“适用于Java:声明”,然后取消选中“ Shorten FQ名称”。给它一个模板文本:

$serial$

现在编辑变量并将序列号设置为:

groovyScript("(System.env.JDK_HOME+'/bin/serialver -classpath '+com.intellij.openapi.fileEditor.FileDocumentManager.instance.getFile(_editor.document).path.replaceAll('/java/.*','').replaceAll('/src/','/build/classes/')+' '+_1).execute().text.replaceAll('.*: *','')",qualifiedClassName())

它采用标准Gradle项目布局。将Maven的/ build /更改为/ target /。


1

最简单的方法现代化:Alt+ Enter

private static final long serialVersionUID = ;

IntelliJ将在=。之后加下划线。将光标放在其上,然后按alt+ Enter(在Mac上为Option+ Enter)。您将看到一个弹出窗口,上面显示“随机更改serialVersionUID初始化程序”。只需按回车键,它将随机填充该空间。


0

如果要为一堆文件添加缺少的serialVersionUID,则IntelliJ IDEA可能无法很好地工作。我提出了一些简单的脚本来轻松实现此目标:

base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes

while read f
do
    clazz=${f//\//.}
    clazz=${clazz/%.java/}
    seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
    perl -ni.bak -e "print $_; printf qq{%s\n}, q{    private $seruidstr} if /public class/" $src_dir/$f
done

您保存此脚本,例如add_serialVersionUID.sh~/bin文件夹中。然后在Maven或Gradle项目的根目录中运行它,如下所示:

add_serialVersionUID.sh < myJavaToAmend.lst

该.lst包含用于以以下格式添加serialVersionUID的Java文件列表:

com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java

该脚本使用JDK serialVer工具。当您想修改最初没有设置serialVersionUID的大量类,同时又要保持与旧类的兼容性时,这是一种理想的选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.