JetBrains @Contract使用字段

时间:2015-02-16 08:54:07

标签: java intellij-idea

我有以下课程*:

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的一部分。

*仅用于演示目的的虚构类:)实际代码使用更复杂的类。

3 个答案:

答案 0 :(得分:7)

您的mString是可变的,因此在检查'isNullOrEmpty'和访问'mString.contains之间可以更改mString值。因此,@Contract注释仅适用于方法参数的原因。如果方法@Contract如下所示,您可以使用isNullOrEmpty

public isNullOrEmpty(String pString) {}

答案 1 :(得分:2)

好吧,因为您已使用mString注释@NullablemString很可能是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;
    }
  }