我使用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的正确处理。

其他回答

总而言之,避免声明

if (object != null) {
    ....
}

由于java7,您可以使用Objects方法:Objects.isNull(对象)Objects.nonNull(对象)Objects.requireOnNull(对象)Objects.equals(object1,object2)从java8开始,您可以使用Optional类(何时使用)

object.ifPresent(obj->…);java 8

object.ifPresentOrElse(对象->…,()->…);java 9

依靠方法契约(JSR305)并使用FindBugs。用annotations@javax.annotation.Nullable和@javax.annotation.Nonnnual标记代码。还提供了前提条件。前提条件.checkNotNull(对象);在特殊情况下(例如字符串和集合),可以使用apachecommons(或Google guava)实用程序方法:

公共静态布尔isEmpty(CharSequence cs)//apache CollectionUtils公共静态布尔isEmpty(集合coll)//apacheStringUtils公共静态布尔isEmpty(Map Map)//apache MapUtils公共静态布尔isNullOrEmpty(@Nullable String字符串)//Guava字符串

当您需要在null时分配默认值时,请使用apachecommons-lang

公共静态对象defaultIfNull(对象对象,对象defaultValue)

根据所检查的对象类型,您可以使用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");

可以在方法调用之前使用拦截器。这就是面向方面编程所关注的。

假设M1(对象测试)是一个方法,M2是一个在方法调用之前应用方面的方法,M2(对象测试2)。如果test2!=null则调用M1,否则执行另一件事。它适用于所有要应用方面的方法。如果要为实例字段和构造函数应用方面,可以使用AspectJ。对于方法方面,Spring也是最佳选择。

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

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

我是“快速失败”代码的粉丝。问问你自己——在参数为空的情况下,你在做什么有用的事情吗?如果在这种情况下,您对代码应该做什么没有明确的答案。。。即,它一开始不应该为空,然后忽略它并允许引发NullPointerException。调用代码将与IllegalArgumentException一样具有NPE的意义,但如果抛出NPE,而不是您的代码试图执行一些其他意外的意外逻辑,那么开发人员将更容易调试和理解出了什么问题-这最终会导致应用程序失败。