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

huangapple go评论28阅读模式
英文:

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

问题

假设我有如下的Java代码

```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();"调用上使用快速修复(<kbd>Ctrl</kbd>+<kbd>1</kbd>)操作"分配语句给新的本地变量"时,我得到了这样的结果:

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

我不想在我的客户端Java代码中看到这个注解,因为对我来说只是噪音。如何防止它每次都生成,并得到下面这种结果?

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

所有这些只在注解具有@Target(TYPE_USE).settings/org.eclipse.jdt.core.prefs中的org.eclipse.jdt.core.compiler.compliance=8或更高时才会发生。

值得一提的是,我还提出了增强请求565463

(实际的API声明了这种注解,以提高与Kotlin的互操作性(使用了JetBrains的注解),因为Kotlin可以用它来区分TT?,并避免T!


<details>
<summary>英文:</summary>

Assuming I have Java code like this:

```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 {}

When I use the quick fix (<kbd>Ctrl</kbd>+<kbd>1</kbd>) action "Assign statement to new local variable" on the "object();" call, I'm getting this:

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

I don't want the annotation in my client Java code as it's just noise for me. How can I prevent it from being generated all the time, and get this instead?

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

All of this only happens when the annotation has @Target(TYPE_USE), and only when org.eclipse.jdt.core.compiler.compliance=8 or later in .settings/org.eclipse.jdt.core.prefs

For the record, I've also filed enhancement request 565463.

(The real world API is declaring such annotations for better Kotlin interoperability (the JetBrains annotations are used), as Kotlin can use it to distinguish between T and T?, and avoid T!)

答案1

得分: 3

@NotNull 在你的情况下不需要,只有在未启用或配置错误的情况下才会添加基于注释的空值分析。

Project > Properies: Java > CompilerNull analysis 部分:

  1. 确保复选框 Enable annotation-based null analysis 已选中
  2. 不要勾选复选框 Use default annotation for null specification,而是点击 Configure... 链接并配置 test.NotNull(或 org.jetbrains.annotations.NotNull)为 'NonNull' annotation

请注意,只会添加 ElementType.TYPE_USE 注释。对于带有 ElementType.TYPE_USE 注释的方法(不能添加到 void 方法),该注释 指的是返回类型,而不是方法本身。换句话说,调用这种方法时会得到一个带注释的对象。对我来说,将类型的注释添加到变量的类型是预期的行为。

仅当注释具有 ElementType.TYPE_USEElementType.METHOD 两个目标 时才会变得 不清楚。该注释是指向返回类型(因此添加它是有意义的),还是方法指向方法本身(因此不应该添加它)?

还请注意,与 org.jetbrains.annotations.NotNull 不同,org.eclipse.jdt.annotation.NonNull 没有目标 ElementType.METHOD。方法声明如何为 null@NotNull 方法的含义是什么?根据 org.jetbrains.annotations.NotNull 的 Javadoc“...方法禁止返回 null 值...”),似乎在这里添加了目标 ElementType.METHOD 是错误的,因为它不涉及 方法声明

英文:

The @NotNull, unwanted in your case, will be added if and only if annotation-based null analysis is not enabled or misconfigured.

In Project > Properies: Java > Compiler in the section Null analysis:

  1. Make sure the checkbox Enable annotation-based null analysis is checked
  2. Instead of the checkbox Use default annotation for null specification being checked, click the Configure... link and configure test.NotNull (or org.jetbrains.annotations.NotNull) as 'NonNull' annotation

Please note, only ElementType.TYPE_USE annotations will be added. For methods annotated with an ElementType.TYPE_USE annotation (which cannot be added to void methods), the annotation refers to the return type, not to the method itself. In other words, you get an annotated object when calling such a method. For me, to add an Use of a type annotations to the type of a variable is the expected behavior.

It only becomes unclear for annotations like in your case that have both targets, ElementType.TYPE_USE and ElementType.METHOD. Does the annotation refer to the return type (so it make sense to add it) or does the method refer to the method itself (and therefore it should not be added)?

Please not also, in contrast to org.jetbrains.annotations.NotNull org.eclipse.jdt.annotation.NonNull has no target ElementType.METHOD. How can a method declaration be null? What is the meaning of a @NotNull method? According to the 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.

答案2

得分: 0

以下是您要翻译的内容:

"While the question is generic, the use-case behind the question is the jOOQ API, which starts adding the Jetbrains annotations in jOOQ 3.14 (see #6244) for better Kotlin interoperability, e.g.

interface ResultQuery&lt;R&gt; {
  @NotNull Result&lt;R&gt; fetch();
  @Nullable R fetchOne();
}

In the case of jOOQ, the dependency on the annotations can be made optional/provided in Maven, or static in JPMS, such that ordinary Java client code doesn't see the annotation by default:

&lt;dependency&gt;
    &lt;groupId&gt;org.jetbrains&lt;/groupId&gt;
    &lt;artifactId&gt;annotations&lt;/artifactId&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
    &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;

The Kotlin compiler can still see it nevertheless:

val q: ResultQuery&lt;R&gt; = ...
q.fetch() // Result&lt;R!&gt;
q.fetchOne() // R?

If a third party out of your control is introducing the dependency, it can be excluded like this:

&lt;dependency&gt;
    &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
    &lt;artifactId&gt;testcontainers&lt;/artifactId&gt;
    
    &lt;exclusions&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;org.jetbrains&lt;/groupId&gt;
            &lt;artifactId&gt;annotations&lt;/artifactId&gt;
        &lt;/exclusion&gt;
    &lt;/exclusions&gt;
&lt;/dependency&gt;
英文:

While the question is generic, the use-case behind the question is the jOOQ API, which starts adding the Jetbrains annotations in jOOQ 3.14 (see #6244) for better Kotlin interoperability, e.g.

interface ResultQuery&lt;R&gt; {
  @NotNull Result&lt;R&gt; fetch();
  @Nullable R fetchOne();
}

In the case of jOOQ, the dependency on the annotations can be made optional/provided in Maven, or static in JPMS, such that ordinary Java client code doesn't see the annotation by default:

&lt;dependency&gt;
    &lt;groupId&gt;org.jetbrains&lt;/groupId&gt;
    &lt;artifactId&gt;annotations&lt;/artifactId&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
    &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;

The Kotlin compiler can still see it nevertheless:

val q: ResultQuery&lt;R&gt; = ...
q.fetch() // Result&lt;R!&gt;
q.fetchOne() // R?

If a third party out of your control is introducing the dependency, it can be excluded like this:

&lt;dependency&gt;
    &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
    &lt;artifactId&gt;testcontainers&lt;/artifactId&gt;
    
    &lt;exclusions&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;org.jetbrains&lt;/groupId&gt;
            &lt;artifactId&gt;annotations&lt;/artifactId&gt;
        &lt;/exclusion&gt;
    &lt;/exclusions&gt;
&lt;/dependency&gt;

huangapple
  • 本文由 发表于 2020年7月22日 22:41:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63036897.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定