将表达式分配给局部变量时如何防止 Eclipse 生成类型注释

How to prevent Eclipse from generating type annotations when assigning expression to local variable

假设我有这样的 Java 代码:

package test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

public class Test {

    @NotNull
    public static Object object() {
        return new Object();
    }

    public static void test() {
        object();
    }
}

@Target({ ElementType.METHOD, ElementType.TYPE_USE })
@interface NotNull {}

当我在“object( );"打电话,我得到这个:

public static void test() {
    @NotNull
    Object object = object();
}

我不想在我的客户端 Java 代码中添加注释,因为它对我来说只是噪音。怎么才能不让它一直生成,取而代之呢?

public static void test() {
    Object object = object();
}

所有这一切只发生在注释有 @Target(TYPE_USE) 时,并且只发生在 org.eclipse.jdt.core.compiler.compliance=8 或更晚的 .settings/org.eclipse.jdt.core.prefs

郑重声明,我还提交了 enhancement request 565463

(现实世界 API 声明这样的注释是为了更好的 Kotlin 互操作性(使用 JetBrains 注释),因为 Kotlin 可以使用它来区分 TT?,并避免 T!)

@NotNull,在你的情况下不需要,当且仅当如果基于注释的空分析未启用或配置错误.

项目 > 属性:Java > 编译器 部分空分析:

  1. 确保复选框启用基于注释的空值分析已选中
  2. 不要选中复选框 为空规范使用默认注释,而是单击 配置... link和配置test.NotNull(或org.jetbrains.annotations.NotNull)为 'NonNull'注释

请注意,只会添加 ElementType.TYPE_USE 个注释。对于使用 ElementType.TYPE_USE 注解的方法(不能添加到 void 方法),注解 指的是 return 类型 ,而不是方法本身。换句话说,当调用这样的方法时,您会得到一个带注释的对象。对我来说,向变量类型添加 Use of a type 注释是预期的行为。

它只会变得不清楚对于像你的情况这样的注释有两个目标,ElementType.TYPE_USEElementType.METHOD.注释是引用 return 类型(因此添加它有意义)还是方法引用方法本身(因此不应添加)?

请不要也,对比org.jetbrains.annotations.NotNullorg.eclipse.jdt.annotation.NonNull没有目标ElementType.METHOD。方法声明怎么可能是null@NotNull 方法的含义是什么?根据 Javadoc of org.jetbrains.annotations.NotNull ("... null value is forbidden to return (for methods)..."), the target ElementType.METHOD seems to be added by mistake here, since it does not refer to the method declaration.

虽然问题是通用的,但问题背后的用例是 jOOQ API,它开始在 jOOQ 3.14 中添加 Jetbrains 注释(参见 #6244)以获得更好的 Kotlin 互操作性,例如

interface ResultQuery<R> {
  @NotNull Result<R> fetch();
  @Nullable R fetchOne();
}

在jOOQ的情况下,可以在Maven中对注释进行依赖optional/provided,或者在JPMS中static,这样普通的Java客户端代码就看不到了默认注释:

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <scope>provided</scope>
    <optional>true</optional>
</dependency>

Kotlin 编译器仍然可以看到它:

val q: ResultQuery<R> = ...
q.fetch() // Result<R!>
q.fetchOne() // R?

如果是你无法控制的第三方引入依赖,可以这样排除:

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    
    <exclusions>
        <exclusion>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
        </exclusion>
    </exclusions>
</dependency>