ChatGPT解决这个技术问题 Extra ChatGPT

IntelliJ IDEA 生成 serialVersionUID

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

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

部分代码:

public class PKladrBuilding extends PRQObject

public abstract class PRQObject extends PObject

public abstract class PObject implements Serializable
你确定你需要产生一个价值,而不是定义你自己的价值吗?如果您正在创建一个新类,我建议您将例如 1L 定义为您的 ID,并在您的序列化表单更改时递增。 (见stackoverflow.com/questions/888335/…)。
stackoverflow.com/questions/24573643/… 有一个很好的解决方案。

P
Peter Mortensen

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

https://i.stack.imgur.com/lpmCC.png

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

https://i.stack.imgur.com/zb5lI.png

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


试试File | Invalidate Caches,如果没有帮助,请联系 support@jetbrains.com 并提供示例项目以进行重现。
检查 idea.log(Help | Reveal Log in ...)是否存在异常,已知 Linux 上的加密主目录会因为 kernel bug 而导致问题。
我有很多例外..比如 java.lang.NoClassDefFoundError: org/intellij/lang/annotations/MagicConstant;
我已经重新安装了 IDEA 并删除了插件,它对我有帮助。 Tnx 很多。
我让它在 v15 中工作的方式是将鼠标悬停在 ClassName 上以查看警告并将鼠标缓慢移向排水沟。此时,“灯泡”出现在屏幕上。 (如果第一次没有按预期工作,请尝试几次)。然后你可以点击创建字段选项来创建uid。希望这可以帮助那些坚持这一点的人。
P
Peter Mortensen

安装 Olivier Descout 的 GenerateSerialVersionUID 插件。

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

安装插件并重新启动。

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


是否真的需要一个外部插件才能使其正常工作?
是的,您需要一个已经是 IntelliJ 插件存储库一部分的插件。
我在 Android Studio 上超时
适用于 2017.3.4 - 我注意到当它在基类中定义时,您无法生成 serialVersionUID(即使它是私有静态的,在这个意义上应该无关紧要)。这个插件只是提供了选项并且可以工作。好的。
答案是正确的,但是每隔几个主要版本就中断的插件不如使用这里发布的内部解决方案好。
N
Nikhil Katre

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

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

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

PS:取自here


谢谢。我不知道为什么我没有看到灯泡,但是点击类名并输入 Alt-Enter 就可以了。
答案从 here 被盗
这是更新的
E
Emdadul Sawon

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

Here is a details comment on this. 我在这里处理评论。

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

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


谢谢,我已经跳过这个简单的事实很长时间了!
当我不想在反序列化时支持旧版本时,我实际上会使用新的随机数重新生成 serialVersionUID。也许我不需要使用随机数,但可以从 1 开始并递增它。但是,3L 对我来说并没有比 -3518231192373568183L 更有意义。因此,我猜这两种解决方案的工作方式相似。不过,随机数可能具有这样的优势,即它可以处理带有分叉和分支的非线性历史。
p
pharsfalvi

为了产生价值使用

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/


喜欢这个评论,使用实时模板,这肯定是最快的解决方案和最可定制的(例如,我删除了换行符)。要进行配置,请转到 Android Studio > Preferences > Editor > Live Templates 并使用此值创建一个新模板(加号图标)并使用编辑变量输入脚本
a
acdcjunior

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

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

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

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

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

现在您可以在类正文中键入 serialTAB


j
jeremysprofile

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

private static final long serialVersionUID = ;

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


A
Alexander

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

https://i.stack.imgur.com/mRT0u.png

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


很好,这为我完成了工作。它找到了丢失的变量并提供了添加它的选项。
Q
Quoc Nguyen

使用版本 v2018.2.1

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

类声明旁边应出现警告。


J
Johnny Wu

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


P
Peter Mortensen

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

您保存此脚本,例如在您的 ~/bin 文件夹中的 add_serialVersionUID.sh。然后在 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 的类同时保持与旧类的兼容性时,它是理想的选择。


P
Peter Mortensen

将名为“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/。