英文:
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可以用它来区分T
和T?
,并避免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 > Compiler 的 Null analysis 部分:
- 确保复选框 Enable annotation-based null analysis 已选中
- 不要勾选复选框 Use default annotation for null specification,而是点击 Configure... 链接并配置
test.NotNull
(或org.jetbrains.annotations.NotNull
)为 'NonNull' annotation
请注意,只会添加 ElementType.TYPE_USE
注释。对于带有 ElementType.TYPE_USE
注释的方法(不能添加到 void
方法),该注释 指的是返回类型,而不是方法本身。换句话说,调用这种方法时会得到一个带注释的对象。对我来说,将类型的注释添加到变量的类型是预期的行为。
仅当注释具有 ElementType.TYPE_USE
和 ElementType.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:
- Make sure the checkbox Enable annotation-based null analysis is checked
- Instead of the checkbox Use default annotation for null specification being checked, click the Configure... link and configure
test.NotNull
(ororg.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<R> {
@NotNull Result<R> 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:
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
The Kotlin compiler can still see it nevertheless:
val q: ResultQuery<R> = ...
q.fetch() // Result<R!>
q.fetchOne() // R?
If a third party out of your control is introducing the dependency, it can be excluded like this:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<exclusions>
<exclusion>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
英文:
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<R> {
@NotNull Result<R> 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:
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
The Kotlin compiler can still see it nevertheless:
val q: ResultQuery<R> = ...
q.fetch() // Result<R!>
q.fetchOne() // R?
If a third party out of your control is introducing the dependency, it can be excluded like this:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<exclusions>
<exclusion>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论