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

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

当前回答

如果不允许未定义的值:

您可以配置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的正确处理。

其他回答

首先,我们不能真正删除所有空条件。我们可以使用@NotNull和@Nullable注释来减少它们(如上所述)。但这需要一些框架的支持。这是OVal可以帮助的地方。

基本思想是对象/参数/构造函数应始终满足前提条件。您可以有很多先决条件,例如Nullable、NotNull和OVal。它们会注意对象在调用时应处于一致状态。

我猜OVal内部使用AspectJ来验证前提条件。

@Guarded
public class BusinessObject
{
  public BusinessObject(@NotNull String name)
  {
    this.name = name;
  }

  ...
}

例如

// Throws a ConstraintsViolatedException because parameter name is null
BusinessObject bo = new BusinessObject(null);

根据所检查的对象类型,您可以使用apachecommons中的一些类,例如:apachecommons-lang和apachecommons集合

例子:

String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}

或(取决于您需要检查的内容):

String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}

StringUtils类只是众多类中的一个;在commons中有相当多的好类可以进行空安全操作。

下面是一个示例,说明当您包含apache库(commons-lang-2.4.jar)时,如何在JAVA中使用空值验证

public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}

如果您使用的是Spring,Spring的包中也有相同的功能,请参见库(Spring-2.46.jar)

关于如何使用spring中的静态类f的示例(org.springframework.util.Assert)

Assert.notNull(validationEventHandler,"ValidationHandler not Injected");

您可以考虑空对象是bug的情况,而不是空对象模式(有其用途)。

当抛出异常时,检查堆栈跟踪并解决错误。

Google集合框架为实现空检查提供了一种良好而优雅的方式。

库类中有一个方法如下:

static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}

用法是(使用import static):

...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...

或者在您的示例中:

checkNotNull(someobject).doCalc();
public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}