314

如何在 IntelliJ IDEA 中生成这个值?

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

部分代码:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
4

12 回答 12

615

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

在此处输入图像描述

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

在此处输入图像描述

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

于 2012-10-16T10:17:06.227 回答
179

安装 Olivier Descout 的GenerateSerialVersionUID插件。

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

安装插件并重新启动。

现在您可以从菜单CodeGenerate → serialVersionUID` 或快捷方式生成id 。

于 2013-08-20T17:29:28.040 回答
78

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

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

现在,如果你的类实现Serializable了,你会看到高亮,并且alt+Enter类名上会建议生成private static final long serialVersionUID

PS:取自这里

于 2017-03-15T05:29:11.273 回答
40

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

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

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

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

于 2017-07-16T04:53:39.743 回答
17

为了产生价值使用

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/

于 2015-03-18T10:01:06.527 回答
14

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

要做到这一点,请按Ctrl+Alt+S->"Live Templates"部分 -> other(或您希望的 w/e)

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

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

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

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

于 2014-09-18T11:59:42.967 回答
11

最简单的现代方法:Alt+ Enteron

private static final long serialVersionUID = ;

IntelliJ 将在=. 将光标放在它上面并点击alt+ Enter(在 Mac 上是 +)OptionEnter你会得到一个弹出窗口,上面写着“Randomly Change serialVersionUID Initializer”。只需按 Enter 键,它就会用随机长度填充该空间。

于 2020-05-06T17:46:07.860 回答
4

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

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

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

于 2019-06-14T07:55:48.427 回答
2

有版本v2018.2.1

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

类声明旁边应出现警告。

于 2018-10-18T01:45:27.420 回答
1

如果要为一堆文件添加缺少的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 包含 Java 文件列表以添加以下格式的 serialVersionUID:

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 的类同时保持与旧类的兼容性时,它是理想的选择。

于 2015-06-27T12:19:39.790 回答
1

将名为“ser”的实时模板添加到另一个组,将其设置为“Applicable in Java: declaration”,并取消选中“Shorten FQ names”。给它一个模板文本:

$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/。

于 2017-02-08T13:01:07.153 回答
1

我正在使用 Android Studio 2.1,通过单击类名称并将鼠标悬停在其上一秒钟,我获得灯泡的一致性更好。

于 2016-06-27T04:10:25.383 回答