我有以下课程*:
public class MyClass {
@Nullable
private String mString;
/* ... */
public boolean contains(@NotNull final String text) {
if(!isNullOrEmpty()) {
return mString.contains(text);
} else {
return false;
}
}
public boolean isNullOrEmpty() {
return mString == null || mString.isEmpty();
}
}
现在在mString.contains(text)
,IntelliJ警告我mString
可能是null
,即使保证不是isNullOrEmpty()
。我注意到JetBrains有@Contract
注释。有没有一种方法可以注释true
,以便在方法返回@Contract
时我不会收到此警告?
我希望//@ ensure \result == true ==> mString != null;
public boolean isNullOrEmpty() {
return mString == null || mString.isEmpty();
}
注释接近Java Modeling Language功能,如下所示:
isNullOrEmpty()
此外,我希望{{1}}保持无参数,因为它是公共API的一部分。
*仅用于演示目的的虚构类:)实际代码使用更复杂的类。
答案 0 :(得分:7)
您的mString
是可变的,因此在检查'isNullOrEmpty
'和访问'mString.contains
之间可以更改mString值。因此,@Contract
注释仅适用于方法参数的原因。如果方法@Contract
如下所示,您可以使用isNullOrEmpty
:
public isNullOrEmpty(String pString) {}
答案 1 :(得分:2)
好吧,因为您已使用mString
注释@Nullable
,mString
很可能是null
。这是工作中的静态分析;你已经声明这个字段可能是null
,也可能不是@Nullable
,所以IntelliJ会告诉你这个。
考虑为何使用@NotNull
注释该字段。也许它应该是contains
?
请记住,我只是在mString == null
方法中收到警告,因为IntelliJ正在做聪明的事情;它知道如果@Contract
,其他条件将不会被评估。
提醒:@Nullable
only applies to the arguments。它不会检查与字段有关的任何内容,这就是为什么会以不同的方式对字段进行注释(使用@NonNull
,@MagicConstant
,{{1}}等。)
答案 2 :(得分:1)
您可以使用@Contract
注释,但您可能需要将isNull方法更改为:
@Contract("null -> true; !null -> false")
private boolean isNull(String value) {
return value == null;
}
然后您应该可以使用其他方法:
public boolean contains(@NotNull final String text) {
if(!isNull(text)) {
return mString.contains(text);
} else {
return false;
}
}
但是,我不确定这会如何更好:
public boolean contains(@NotNull final String text) {
if(text != null) {
return mString.contains(text);
} else {
return false;
}
}