我使用x!=null以避免NullPointerException。还有其他选择吗?

if (x != null) {
    // ...
}

当前回答

我发现在这种情况下,Guava前提条件非常有用。我不喜欢将空值留给空指针异常,因为理解NPE的唯一方法是定位行号。生产版本和开发版本中的行号可能不同。

使用Guava Preconditions,我可以检查空参数并在一行中定义有意义的异常消息。

例如

Preconditions.checkNotNull(paramVal, "Method foo received null paramVal");

其他回答

通过遵循问题的大多数其他答案,您可以避免很多事情,以避免NullPointerException。我只想添加Java9中引入的其他一些方法,以优雅地处理这种情况,并展示一些旧的方法也可以使用,从而减少您的工作量。

公共静态布尔值isNull(对象obj)如果提供的引用为null,则返回true,否则返回错误。自Java 1.8以来公共静态布尔值nonNull(对象obj)如果提供的引用为非null,则返回true,否则返回错误。自Java 1.8以来公共静态<T>T requireOnNullElse​(T对象,T默认对象)如果第一个参数为非null,则返回第一个参数,否则返回非空的第二个参数。自Java 9以来公共静态<T>T requireOnNullElseGet​(T obj,供应商<?扩展T>供应商)如果第一个参数为非空,则返回第一个参数,否则返回supplier.get()的非空值。自Java 9以来公共静态<T>T requireOnNull​(T obj,供应商<字符串>消息供应商)检查指定的对象引用是否为空,否则将引发自定义的NullPointerException。自Java 1.8以来

有关上述功能的更多详细信息,请参阅此处。

对于实用程序类,可以检查参数是否为空。

在所有其他情况下,您可能不必这样做。尽可能使用封装,从而减少您想检查null的地方。

Guava是Google提供的一个非常有用的核心库,它有一个很好且有用的API来避免空值。我发现UsingAndAvoidingNullExplain非常有用。

正如wiki中所解释的:

可选<T>是用非空值。可选可以包含非空T引用(在这种情况下,我们称引用为“present”),或者它可能包含什么都没有(在这种情况下,我们说引用“不存在”)。从来没有称为“包含null”

用法:

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5

您可以为对象和字符串创建一个通用方法,以便在应用程序中完全使用它-这可以帮助您和您的同事:创建一个类,例如StringUtilities,并添加方法,例如getNullString

public static String getNullString(Object someobject)
{
   if(null==someobject )
        return null;

   else if(someobject.getClass().isInstance("") && 
          (((String)someobject).trim().equalsIgnoreCase("null")|| 
          ((String)someobject).trim().equalsIgnoreCase("")))
        return null;

   else if(someobject.getClass().isInstance(""))
        return (String)someobject;

   else
        return someobject.toString().trim();
}

简单地将此方法称为,

if (StringUtilities.getNullString(someobject) != null)
{ 
  //Do something
}

如果不允许未定义的值:

您可以配置IDE以警告您可能的空取消引用。例如,在Eclipse中,请参阅首选项>Java>编译器>错误/警告/空分析。

如果允许未定义的值:

如果您想定义一个新的API,其中未定义的值是有意义的,请使用OptionPattern(可能在函数语言中很熟悉)。它具有以下优点:

API中明确说明是否存在输入或输出。编译器强制您处理“未定义”的情况。选项是monad,因此不需要进行冗长的空检查,只需使用map/foreach/getOrElse或类似的组合符即可安全地使用该值(示例)。

Java 8内置了可选类(推荐);对于早期版本,有一些库选项,例如Guava的Optional或FunctionalJava的Option。但是,像许多函数样式模式一样,在Java中使用Option(甚至是8)会产生一些样板,您可以使用不那么冗长的JVM语言(例如Scala或Xtend)来减少这些样板。

如果必须处理可能返回null的API,那么在Java中就做不了什么了。Xtend和Groovy有Elvis运算符?:和空安全解引用运算符?。,但请注意,如果引用为null,则返回null,因此它只是“延迟”了对null的正确处理。