Java IntelliJ IDEA生成serialVersionUID

Java IntelliJ IDEA生成serialVersionUID,java,serialization,intellij-idea,Java,Serialization,Intellij Idea,如何在IntelliJ IDEA中生成此值 我转到设置->错误->序列化问题->不带“serialVersionUID”的可序列化类,但它仍然没有显示警告。我的类PKladrBuilding父类实现了可序列化的接口 守则的一部分: public class PKladrBuilding extends PRQObject public abstract class PRQObject extends PObject public abstract class PObject implemen

如何在IntelliJ IDEA中生成此值

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

守则的一部分:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable

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

如果我试着上第一节课,我会看到:

顺便说一句:直到我在每个类的末尾添加了
{}
来修复编译错误,它才向我显示警告。

安装Olivier Descout的插件

转到:菜单文件→ 设置→ 插件→ 浏览存储库→ <代码>GenerateSerialVersionId

安装插件并重新启动


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

此外,您可以添加将完成此工作的活动模板

要执行此操作,请按Ctrl+Alt+S->“Live Templates”部分->
其他(或按您的意愿)

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

private static final long serialVersionUID = 1L;
$END$
然后选择
definition
scope并将其另存为
'serial'


现在,您可以在类主体中键入
serial
选项卡。

以生成值use

private static final long serialVersionUID = $randomLong$L;
$END$
并为randomLong模板变量提供以下值: groovyScript(“new Random().nextLong().abs()”)


如果要为一组文件添加缺少的SerialVersionID,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

此脚本使用JDK serialVer工具。当您想要修改大量没有设置serialVersionUID的类,同时保持与旧类的兼容性时,它非常适合这种情况。

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

添加一个将名为“ser”的活动模板添加到另一个组,将其设置为“applicative 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项目布局。更改/build/to/target/for Maven。

无需任何插件:只需在IntelliJ中启用高亮显示:

IntelliJ首选项->编辑器->检查->Java->序列化问题->不带“serialVersionUID”的可序列化类
-设置标志并单击
“确定”

现在,如果您的类实现了
Serializable
,您将看到高亮显示,并且类名上的
alt+Enter
将建议生成
私有静态最终长serialVersionUID


PS:取自

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

我在这里回应这一评论

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


希望这有帮助。祝你好运。

版本
v2018.2.1

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


类声明旁边应显示一条警告。

生成serialVersionUID的另一种方法是使用上下文菜单(或键盘快捷键,默认情况下为ctrl+alt+shift+i)中的
按名称运行检查,然后键入“serialVersionUID”而不使用“serialVersionUID”的Serializable类”(或简单键入“serialVersionUID”提前输入功能会为您找到它

然后,您将获得一个上下文菜单,您可以在其中选择在何处运行检查(例如,所有来自特定模块、整个项目、一个文件等)

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

Easie
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())
private static final long serialVersionUID = ;