【问题标题】:How to prevent Eclipse from adding @NotNull annotation when assigning jOOQ expression to local variable将jOOQ表达式分配给局部变量时如何防止Eclipse添加@NotNull注释
【发布时间】:2021-04-01 05:14:37
【问题描述】:

从 jOOQ 3.14 开始,当使用 jOOQ 的代码如下:

DSL.val(1);

我喜欢将上面的表达式分配给一个局部变量,所以我使用了 Eclipse IDE 快速修复操作“Assign statement to new local variable”,它添加了这个导入:

import org.jetbrains.annotations.NotNull;

并生成以下代码:

@NotNull
Param<Integer> val = DSL.val(1);

IntelliJ 不会发生这种情况,它的 “引入局部变量” 快速修复会生成所需的代码:

Param<Integer> val = DSL.val(1);

如何防止不必要地插入@NotNull 注释?

【问题讨论】:

  • 根本原因是 jOOQ 包含来自 JetBrains 的空注释以支持非供应商中立的编程语言 Kotlin,并且这些空注释存储在字节码中,这在技术上不是必需的(并且不在符合 Java 语言规范),但这种 hack 让 JetBrains 更容易实现他们的工具。运行使用 jOOQ 的应用程序时,JetBrains 空注解无故占用内存。
  • @howlger:是的,这就是根本原因。许多库已经开始使用这些注释,它们可能存在您提到的缺陷,但这不是重点。这个问题是关于 Eclipse 快速修复行为的。
  • 公平地说,您问 “如何防止这种情况发生?” 可以通过在 jOOQ 的字节码中没有空注释或至少没有 @987654326 来防止它@ 方法的注解。也许已经有一种方法(或 JetBrains 正在研究它)提供 Kotlin 支持而无需在字节码中添加注释,因为它们在运行时无用。或者 jOOQ(你的作者)可以通过额外的 API/JAR 提供 Kotlin 支持。 “待处理的错误” 是您几个月前报告的一项增强功能,目前似乎没有人在研究您提出的“解决方案”。
  • “公平地说,你问了” - 假装别人问了这个问题。我经常使用 SO 作为外部常见问题解答,这是 SO 鼓励的。 “jOOQ 可以通过 [...] 提供 Kotlin 支持” - 这是一个非常容易实现且方便的结果。对于 kotlin 可空性支持,我认为没有比使用此类注释更好的解决方案了。 jOOQ 没有退路。 “目前似乎没有人在工作” - 当然,不用担心。此处的此问答旨在帮助人们了解正在发生的事情,并更好地找到解决方法。我被问过几次这个问题。
  • 那些考虑为他们的框架也提供 Kotlin 支持的人应该知道,这意味着注释将被添加到他们的类文件中,因为 JetBrains 使用了一个肮脏的技巧。所以他们可能会要求 JetBrains 解决这个问题。在 Eclipse 中,很少使用的 TYPE_USE 注释有一个特殊的行为,这是有意义的(在这一点上我们不同意)。但是,Eclipse 可以通过默认理解广泛使用的空注释来做得更好,这将导致此处的行为不同并更好地检测问题。

标签: java eclipse jooq notnull


【解决方案1】:

Eclipse 中有一个待解决的错误来解决这个问题:https://bugs.eclipse.org/bugs/show_bug.cgi?id=565463。当前行为的基本原理(在 2020-12 (4.18.0) 中仍然存在)可以在该问题中看到。

一种解决方法是在 Preferences > Java Compiler > Errors/Warnings > Enable annotation-based null analysis 中打开基于注释的 null 分析

... 并将 jetbrains 注释设置为主要和/或次要注释:

Eclipse 可能找不到注释,在这种情况下,解决方法可能是手动编辑项目的 .settings/org.eclipse.jdt.core.prefs 文件,添加这些:

org.eclipse.jdt.core.compiler.annotation.nonnull=org.jetbrains.annotations.NotNull
org.eclipse.jdt.core.compiler.annotation.nullable=org.jetbrains.annotations.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled

这种解决方法的副作用当然是空分析现在在 jOOQ 代码上处于活动状态,这可能是也可能不是您想要的。

【讨论】:

  • 此设置不会强制您在自己的代码中使用空注释。您甚至可以通过将这些问题的严重性设置为 Ignore 来禁止显示这些空问题。但是,例如,当调用一个非空参数设置为空的 jOOQ 方法时,为什么不想出现错误呢? jOOQ 是否包含错误的空注释?
  • @howlger:这个问答(以及链接的 Eclipse 问题)与 Eclipse 空值分析功能无关。我只是在这里记录一个解决方法以获得更好的可见性。无论如何,我已经在问题中向您解释了我的观点......
  • 在错误报告中,您说这会导致 “必须选择加入 Eclipse 空值检查功能”,在这里您说 “现在是空值分析在 jOOQ 代码上活跃”,我认为这不是真的,没有解释它。从我的角度来看,应该改进 Eclipse (1) 通过预先配置广泛使用的空注释和 (2) 通过不要求这些注释位于 Java 构建路径上(默认情况下)。在我看来,Eclipse 对 TYPE_USE 注释的行为符合 Java 语言规范。所以这里不应该有任何改变。您提出什么解决方案?
  • @howlger:我正在重新记录观察到的启用此 Eclipse 功能的解决方法,作为副作用,它使用@Nullable@NotNull 走开。我提出的解决方案与 Eclipse 问题中的相同。应该可以将 Eclipse 配置为不在客户端代码中插入任何 TYPE_USE 注释 1) 根本,2) 如果它们匹配某些包含/排除模式,3) 一些其他管理哪些 TYPE_USE 注释感兴趣的方法,以及哪些那些不是。具体来说,如果注释不在客户端类路径上,则不得插入。
  • 出于同样的原因,有人可能会争辩说,对于由方法调用返回的类型,Eclipse 应该为未知类型插入Object,而对于泛型类型则插入其原始类型。方法上的TYPE_USE 注释是指返回的内容,TYPE_USE 不是用于注释方法本身。我提出的解决方案有什么问题?
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 2015-03-23
  • 1970-01-01
  • 2015-10-18
  • 2018-12-07
  • 1970-01-01
  • 2016-01-01
相关资源
最近更新 更多