【问题标题】:How to avoid null warning when using @NotNull and checking for null in another method before method call?使用@NotNull 并在方法调用之前在另一个方法中检查null 时如何避免null 警告?
【发布时间】:2017-06-24 17:26:07
【问题描述】:

我有一个复杂的验证系统,简化后如下所示:

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() 时收到关于“参数 x 可能为空”的警告,即使之后的 methodSelect() 和 switch 语句确保这些参数不会为空。 如何正确消除这些警告,希望在这些方法中或之前无需再次检查 null? 谢谢!

我正在使用 IntelliJ IDEA 2016.3.4、Java 8 和注释:

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

【问题讨论】:

    标签: java intellij-idea annotations nullable notnull


    【解决方案1】:

    这是非常棘手的代码——您正在模仿反射来根据运行时测试调用不同的方法。

    在 IntelliJ IDEA 中,您需要在 IDE 或通过 code annotation 中抑制警告。

    其他一些工具具有更复杂的代码分析。 这是您的代码的一个轻微变体,它使用布尔值而不是字符串来指示要调用的方法。 Checker 框架的Nullness Checker 能够验证此代码的空值安全性,这要归功于后置条件注释@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 注释当前不处理原始代码中使用的字符串;您可以向维护者请求这样的扩展,或者自己实现它并提交拉取请求。

    【讨论】:

    • 感谢您的精彩回答!
    猜你喜欢
    • 2010-12-27
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 2016-08-07
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多