检查 NullPointerException、正确性或个人信仰?

Checking for NullPointerException, correctness or personal belief?

在我的代码中,我对 null 进行了大量检查,这样我就不会得到 NullPointerException 通常我只是这样做:

if(variable != null){
    //do something with the variable
}

以下是更好的方法还是只是个人的看法?

if( !variable.equals(null) ){
    //do something with the variable
}

是否有更有效的方法来进行此检查?

顺便说一句,我确实已经完成了我的研究,但我似乎找不到具体的证据来证明这两点。

P.S 这是 Avoiding != null statementsNOT 副本,最佳答案是您应该使用 Assert,它不能用于运行 代码而不是仅仅显示一条消息,或者实际上抛出我也不想要的异常。此 post 正在解决同一主题的不同问题。

 if(!variable.equals(null) ){
     //do something with the variable
 }

如果变量为空,则发生NPE。第一种方法要好得多。

编辑: 使用可选: 假设您有 Person 个对象并想要 getSalary()。不幸的是 age 可以为 null - 在这种情况下你需要默认值。你可以做到 Integer salary = Optional.ofNullable(person.getSalary()).orElse(2000)。如果薪水为空,它将 return 人的薪水或 2000。

有两种方法:

public void calculate(Class variable) {
    Assert.notNull(variable, "variable was null");
    //calculations
}
//and
if (variable == null) {
    //bad
} else {
    calculate(variable);
}

第二个是最常见的。如果你的变量是 String 考虑使用 Guava.StringUtils 和它很棒的 isBlank 方法检查 Stringnull 还是 ""

总结:

if (variable == null) {
    //bad
} else {
    //good
}

以上是标准做法。更好的方法是:

private boolean isNull(Class variable) {
    return variable == null;
}

if (isNull(variable)) {

} else {

}

我曾经一直调用下面的方法来检查空指针异常

public static boolean isAvailable(Object data) {
        return ((data!=null) && (data.toString().trim().length() > 0));
    } 

正如其他人所说,变体

if(!variable.equals(null))

当变量为空时,可以 NPE 本身。此外,您必须确保 equals 方法对于您使用的所有对象类型也是空安全的。因此,如果您绝对需要检查,请使用 ==.

至于更好的解决方案(我们将在这里基于意见):我认为这种强制性的空值检查是脆弱的软件和次优接口定义的标志。我目前越来越多地尝试做的是使用 javax.validation 注释 @NotNull 来强化我的接口并摆脱所有这些运行时检查:

private @NotNull String getName() {...} // guaranteed not to return null
...
if(getName() == null) { // superfluos, your IDE gives a shout if configurd correctly
   ...
}

...试一试:)

编辑(作为对评论的回答,因为我需要代码格式化):

这是我当前的 eclipse 设置中的完整剪切和粘贴示例:

package stuff;

import javax.validation.constraints.NotNull;

public class Try3 {
   public @NotNull String getName() { return ""; }

   public void test() {
      if(getName() == null)
         System.out.println("Cannot happen due to contract");
   }
}

确保导入的类型确实是 javax.validation.constraints.NotNull(因为其他框架也有 NotNull 注释,可能以不同的方式定义)。对于eclipse,还得在JavaCompiler/Errors/Warnings下的项目设置中勾选"Enable annotation-based null analysis",自定义要使用的注解,因为eclipse默认是一些自制的注解。可以通过在同一设置页面中使用默认注释复选框后的 link "Configure" 访问自定义。希望对您有所帮助!

或者您可以使用 Java 8.

中的 java.util.Optional

JavaCodeGeeks 上有很好的示例。

Optional 通常用于 java.util.stream lambdas for "functional-style operations"。