在方法调用之前使用 @NotNull 并在另一个方法中检查 null 时如何避免空警告?

How to avoid null warning when using @NotNull and checking for null in another method before method call?

我有一个有点复杂的验证系统,简化后的样子如下:

private static void mainMethod(@Nullable String startParam, @Nullable String nextParam) {

    String nextStep = methodSelect(startParam, nextParam);

    switch (nextStep) {
        case "none":
            break;
        case "goFinal":
            finalMethod(startParam);
            break;
        case "goNext":
            nextMethod(nextParam);
            break;
    }
}

private static void nextMethod(@NotNull String nextParam) {
    System.out.println(nextParam);
}

private static void finalMethod(@NotNull String startParam) {
    System.out.println(startParam);
}

@NotNull
private static String methodSelect(@Nullable String startParam,@Nullable String nextParam) {
    if (startParam == null && nextParam == null) {
        return "none";
    } if (startParam == null) {
        return "goNext";
    } else {
        return "goFinal";
    }
}

但是当在 switch 语句中同时调用 finalMethod() 和 nextMethod() 时我收到警告 "Argument x might be null",即使 methodSelect() 和之后的 switch 语句确保这些参数不会为 null。 我如何正确地消除这些警告,希望在这些方法中或之前不再次检查 null? 谢谢!

我正在使用 IntelliJ IDEA 2016.3.4,Java 8,以及注释:

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

这是非常棘手的代码 -- 您正在模仿反射以根据 run-time 测试调用不同的方法。

在 IntelliJ IDEA 中,您需要抑制 IDE or via a 中的警告。

其他一些工具具有更复杂的代码分析。 这是您的代码的一个细微变体,它使用布尔值而不是字符串来指示要调用的方法。 Nullness Checker of the Checker Framework is able to verify the nullness-safety of this code, thanks to the postcondition annotation @EnsuresNonNullIf.

import org.checkerframework.checker.nullness.qual.*;

class Example {

  private static void mainMethod(@Nullable String startParam, @Nullable String nextParam) {

    if (! useFinal(startParam)) {
      // do nothing
    } else {
      finalMethod(startParam);
    }
  }

  private static void nextMethod(@NonNull String nextParam) {
    System.out.println(nextParam);
  }

  private static void finalMethod(@NonNull String startParam) {
    System.out.println(startParam);
  }

  @EnsuresNonNullIf(expression="#1", result=true)
  private static boolean useFinal(@Nullable String startParam) {
    if (startParam == null) {
      return false;
    } else {
      return true;
    }
  }

}

@EnsuresNonNullIf 注解当前无法处理原始代码中使用的字符串;您可以向维护者请求此类扩展或自己实施并提交拉取请求。