为什么我的项目中不存在@NotNull 或@Nullable?
Why doesn't @NotNull or @Nullable exist in my project?
我正在使用 IntelliJ 进行编程,我刚刚在做一个 Java 项目,我想制作一个注释为 @NotNull
的参数。但是 IntelliJ 说它不存在。我已经检查了所有 java 文件,但它不在我的项目中。我很困惑,我没有使用 maven 或 gradle,只是默认的 Java 项目。我不知道发生了什么。
这是一个例子:
package com.company;
public class Main {
public static void main(String[] args){
testF(null);
}
public static void testF (@NotNull Integer... numbers){
for(Integer integer: numbers){
System.out.println(integer);
}
}
}
说“无法解析符号 NotNul : 10”时出错(再次@在前面)
Java 本身不附带这些注释。
相反,大约有 10 个相互不兼容的想法,其中大部分的工作方式完全不同,并且对 NonNull
的含义、放置位置以及工作方式有不同的含义。
哎呀。这是非常不幸的,因为使用注释来添加此信息的基本思想远远优于 Optional 等,因为它完全向后兼容并且不会将现有代码降级为过时的低迷,这与 Optional
不同。
所以,找到一个你喜欢的,并将它包含在你的项目中,就像你包含任何第三方依赖项一样 - 通常通过将它包含在你的 Maven/Gradle/Ant+ivy/etc(你的构建文件的列表依赖项)。
Intellij 对 NonNull 和 Nullable 有自己的看法。这可能是最方便的。它关于这些注释的含义的想法是劣等的1。 Checker Framework 是最好的,eclipse 远远排在第二,其他一切(包括 intellij 的)都排在第三位。最好的方法是在 Checker Framework 中找到,或者几乎同样好,eclipse 对这些注释的看法。但是,我怀疑 intellij 的 null 检查系统是否能够完全理解其更高级的添加,例如 @PolyNull
,因此这种额外的表达能力将大部分被浪费掉。作为奖励,intellij 附带了一堆关于主要库上正确的无效注释的数据。
最后一个很重要:最常用的 java 库,包括 java.*
本身, 没有这些注释 ,并且使用 half-空注释代码绝对是一个非常令人沮丧的练习;这样做的成本远远超过收益。唯一真正的解决方案是 'fix' 您使用的库具有正确的无效信息,但这是一项大量的工作。幸运的是,intellij 已经为你做了很多。
我希望(eclipse 这样做),quickfix(在 mac 上为 CMD+1,在非 mac 上为 CTRL+1,至少,如果我对默认键盘快捷键的记忆对我有用的话,开箱即用)包括“自动将 eclipse 的无效注释添加到类路径”(或者在您的情况下,当然是 intellij)。如果不知何故没有出现,This page from the intellij docs 准确解释如何将包含它们的无效注释的 org.jetbrains.annotations
库添加到您的项目中。事实上,这些文档表明,quickfix 菜单确实为您提供了自动添加此库的选项,作为您在源代码中的 @NonNull
节点上遇到的错误的解决方案。
[1] 大多数采用无效注释通过仅允许在字段、方法(暗示:它是什么 returns)和参数上进行注释来极大地限制自己。但是,可以有一个 definitely-not-null List
of could-be-null Map
实例,其中 Map definitely not null String
to could be null Integer
: @NonNull List<@Nullable Map<@NonNull String, @Nullable Integer>>
。注释系统能够让你这样写,但前提是你的注释是专门为 TYPE_USE 设置的。检查器框架和 Eclipse 的无效注释就是这样工作的;大多数其他人没有,因此表现力较差。 CheckerFramework 更进一步,让您可以编写 'either nullity is fine' 的概念。就像泛型有 3 种形式(List<Integer>
,List<? super Integer>
和 List< extends Integer>
,一旦涉及到泛型,2 个 nullities(要么从不为 null,要么绝对允许 null)就不再足够了,你需要更多的空值。检查器框架有 @PolyNull
会让你 link 空值:例如,你可以在 checkerframework 中编写这个方法,但你不可能用 intellij 或 eclipse 正确地写它:
public void duplicateFirstMatch(List<T> elems, Predicate<T> matcher);
想法是:此方法针对列表中的每个元素运行匹配器,并且在匹配时,将该元素添加到列表的末尾。如果 T
被认为是 '@NonNull'(假设没有空值,则此代码永远不能添加空值,因此它不能违反其元素的非空性),此方法可以工作,但它如果 T
是 @Nullable
,当然也可以工作,只要匹配器也是 @Nullable T
:现在这段代码可能会将 null 添加到列表中,但没关系。
因此 T
既不是 Nullable 也不是 NonNull,但是签名中提到的 T 确实需要匹配它们的空值。 @PolyNull
解决了这个问题。
我正在使用 IntelliJ 进行编程,我刚刚在做一个 Java 项目,我想制作一个注释为 @NotNull
的参数。但是 IntelliJ 说它不存在。我已经检查了所有 java 文件,但它不在我的项目中。我很困惑,我没有使用 maven 或 gradle,只是默认的 Java 项目。我不知道发生了什么。
这是一个例子:
package com.company;
public class Main {
public static void main(String[] args){
testF(null);
}
public static void testF (@NotNull Integer... numbers){
for(Integer integer: numbers){
System.out.println(integer);
}
}
}
说“无法解析符号 NotNul : 10”时出错(再次@在前面)
Java 本身不附带这些注释。
相反,大约有 10 个相互不兼容的想法,其中大部分的工作方式完全不同,并且对 NonNull
的含义、放置位置以及工作方式有不同的含义。
哎呀。这是非常不幸的,因为使用注释来添加此信息的基本思想远远优于 Optional 等,因为它完全向后兼容并且不会将现有代码降级为过时的低迷,这与 Optional
不同。
所以,找到一个你喜欢的,并将它包含在你的项目中,就像你包含任何第三方依赖项一样 - 通常通过将它包含在你的 Maven/Gradle/Ant+ivy/etc(你的构建文件的列表依赖项)。
Intellij 对 NonNull 和 Nullable 有自己的看法。这可能是最方便的。它关于这些注释的含义的想法是劣等的1。 Checker Framework 是最好的,eclipse 远远排在第二,其他一切(包括 intellij 的)都排在第三位。最好的方法是在 Checker Framework 中找到,或者几乎同样好,eclipse 对这些注释的看法。但是,我怀疑 intellij 的 null 检查系统是否能够完全理解其更高级的添加,例如 @PolyNull
,因此这种额外的表达能力将大部分被浪费掉。作为奖励,intellij 附带了一堆关于主要库上正确的无效注释的数据。
最后一个很重要:最常用的 java 库,包括 java.*
本身, 没有这些注释 ,并且使用 half-空注释代码绝对是一个非常令人沮丧的练习;这样做的成本远远超过收益。唯一真正的解决方案是 'fix' 您使用的库具有正确的无效信息,但这是一项大量的工作。幸运的是,intellij 已经为你做了很多。
我希望(eclipse 这样做),quickfix(在 mac 上为 CMD+1,在非 mac 上为 CTRL+1,至少,如果我对默认键盘快捷键的记忆对我有用的话,开箱即用)包括“自动将 eclipse 的无效注释添加到类路径”(或者在您的情况下,当然是 intellij)。如果不知何故没有出现,This page from the intellij docs 准确解释如何将包含它们的无效注释的 org.jetbrains.annotations
库添加到您的项目中。事实上,这些文档表明,quickfix 菜单确实为您提供了自动添加此库的选项,作为您在源代码中的 @NonNull
节点上遇到的错误的解决方案。
[1] 大多数采用无效注释通过仅允许在字段、方法(暗示:它是什么 returns)和参数上进行注释来极大地限制自己。但是,可以有一个 definitely-not-null List
of could-be-null Map
实例,其中 Map definitely not null String
to could be null Integer
: @NonNull List<@Nullable Map<@NonNull String, @Nullable Integer>>
。注释系统能够让你这样写,但前提是你的注释是专门为 TYPE_USE 设置的。检查器框架和 Eclipse 的无效注释就是这样工作的;大多数其他人没有,因此表现力较差。 CheckerFramework 更进一步,让您可以编写 'either nullity is fine' 的概念。就像泛型有 3 种形式(List<Integer>
,List<? super Integer>
和 List< extends Integer>
,一旦涉及到泛型,2 个 nullities(要么从不为 null,要么绝对允许 null)就不再足够了,你需要更多的空值。检查器框架有 @PolyNull
会让你 link 空值:例如,你可以在 checkerframework 中编写这个方法,但你不可能用 intellij 或 eclipse 正确地写它:
public void duplicateFirstMatch(List<T> elems, Predicate<T> matcher);
想法是:此方法针对列表中的每个元素运行匹配器,并且在匹配时,将该元素添加到列表的末尾。如果 T
被认为是 '@NonNull'(假设没有空值,则此代码永远不能添加空值,因此它不能违反其元素的非空性),此方法可以工作,但它如果 T
是 @Nullable
,当然也可以工作,只要匹配器也是 @Nullable T
:现在这段代码可能会将 null 添加到列表中,但没关系。
因此 T
既不是 Nullable 也不是 NonNull,但是签名中提到的 T 确实需要匹配它们的空值。 @PolyNull
解决了这个问题。