IntelliJ IDEA 生成 serialVersionUID
Posted
技术标签:
【中文标题】IntelliJ IDEA 生成 serialVersionUID【英文标题】:IntelliJ IDEA generating serialVersionUID 【发布时间】:2012-10-06 09:51:12 【问题描述】:如何在 IntelliJ IDEA 中生成这个值?
我去设置 -> 错误 -> 序列化问题 -> 没有'serialVersionUID'的可序列化类,但它仍然没有给我看警告。我的类 PKladrBuilding 父级实现 interface Serializable。
部分代码:
public class PKladrBuilding extends PRQObject
public abstract class PRQObject extends PObject
public abstract class PObject implements Serializable
【问题讨论】:
您确定需要生成值,而不是定义自己的值吗?如果您正在创建一个新类,我建议您定义例如1L
作为您的 ID,并在您的序列化表单更改时递增。 (见***.com/questions/888335/…)。
***.com/questions/24573643/… 有一个很好的解决方案。
【参考方案1】:
最简单的现代方法:Alt
+Enter
on
private static final long serialVersionUID = ;
IntelliJ 将在=
之后的空格加下划线。将光标放在上面并点击alt
+Enter
(Mac 上为Option
+Enter
)。你会得到一个弹出窗口,上面写着“Randomly Change serialVersionUID Initializer”。只需按 Enter 键,它就会用随机长度填充该空间。
【讨论】:
【参考方案2】:另一种生成serialVersionUID的方法是使用上下文菜单中的>Analyze >Run Inspection by Name
(或键盘快捷键,即ctrl+alt+shift +i 默认),然后输入“Serializable class without 'serialVersionUID'”(或简单地输入“serialVersionUID”,提前输入函数会为您找到它。
然后,您将获得一个上下文菜单,您可以在其中选择在何处运行检查(例如,所有来自特定模块、整个项目、一个文件......)
使用这种方法,您甚至不必将一般检查规则设置为任何内容。
【讨论】:
很好,这对我有用。它找到了丢失的变量并提供了添加它的选项。【参考方案3】:没有任何插件:您只需要在 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被盗 这是最新的【参考方案4】:使用版本v2018.2.1
前往
Preference > Editor > Inspections > Java > Serialization issues > 切换“Serializable class without 'serialVersionUID'”。
类声明旁边应出现警告。
【讨论】:
【参考方案5】:将名为“ser”的活动模板添加到另一个组,将其设置为“适用于 Java:声明”,并取消选中“缩短 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/。
【讨论】:
【参考方案6】:如果你想为一堆文件添加缺少的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 的类同时保持与旧类的兼容性时,它是理想的选择。
【讨论】:
【参考方案7】:安装 Olivier Descout 的 GenerateSerialVersionUID 插件。
转到:菜单文件 → 设置 → 插件 → 浏览存储库 → GenerateSerialVersionUID
安装插件并重启。
现在您可以从菜单代码 → 生成 → serialVersionUID`或快捷方式生成id。
【讨论】:
真的需要一个外部插件才能让它工作吗? 是的,您需要一个已经是 IntelliJ 插件存储库一部分的插件。 android Studio 超时 在 2017.3.4 中工作 - 我注意到当它在基类中定义时,您无法生成 serialVersionUID(即使它是私有静态的,在这个意义上应该无关紧要)。这个插件只是提供了选项并且可以工作。不错。 答案是正确的,但是每隔几个主要版本就破解的插件不如使用这里发布的内部解决方案。【参考方案8】:我不确定您是否有旧版本的 IntelliJ IDEA,但如果我转到菜单 File → Settings... → Inspections em> → 序列化问题 → 未启用 'serialVersionUID'` 的可序列化类,您提供的类会给我警告。
如果我尝试我看到的第一堂课:
顺便说一句:直到我在每个类的末尾添加
以修复编译错误时,它才显示警告。
【讨论】:
试试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。希望这可以帮助那些陷入困境的人。【参考方案9】:
此外,您可以添加可以完成工作的实时模板。
要做到这一点,请按 Ctrl+Alt+S -> "Live Templates"
部分 -> other
(或您希望的)
然后创建一个新的,定义如下:
private static final long serialVersionUID = 1L;
$END$
然后选择definition
范围并保存为'serial'
现在您可以在类正文中输入serial
TAB。
【讨论】:
【参考方案10】:在序列化上花了一些时间后,我发现,我们不应该生成带有一些随机值的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
更有意义。因此,我猜这两种解决方案的工作方式相似。不过,随机数的优势可能在于它可以处理带有分叉和分支的非线性历史。【参考方案11】:
我使用的是 Android Studio 2.1,通过单击类名称并将鼠标悬停在其上一秒钟,我获得灯泡的一致性更好。
【讨论】:
【参考方案12】:为了生成值使用
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 并使用此值创建一个新模板(加号图标)并使用编辑变量输入脚本以上是关于IntelliJ IDEA 生成 serialVersionUID的主要内容,如果未能解决你的问题,请参考以下文章
macbook intellij idea 怎么生成get set
Idea_Intellij Idea 12 生成serialVersionUID的方法