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

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

当前回答

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

正如wiki中所解释的:

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

用法:

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

其他回答

避免不必要的空检查的方法很简单:

您需要知道哪些变量可以为空,哪些变量不能为空,并且您需要对给定变量属于哪一类有信心。

但是,尽管它可以说得很简单,但实现它却很困难。关键在于自信的部分,因为你如何确定变量不能为空?

对此没有快速的解决方法,但这里有一些提示:

干净的代码。能够推理一段代码的行为最重要的一点是,它是以易于理解的方式编写的。根据变量所代表的内容命名变量,根据它们所做的内容命名方法,应用单一责任原则(SOLID中的S:http://en.wikipedia.org/wiki/SOLID_(object-oriented_design),这意味着每一段代码都应该有一个单独的责任,并且不做任何其他事情)。一旦你的代码是干净的,那么你就更容易理解它,也更容易理解多个代码层。对于杂乱的代码,试图理解一个方法的作用可能会让你忘记当初为什么要读这个方法。(提示:阅读罗伯特·C·马丁的《清洁代码》)避免返回空值。如果空值会使程序无法正常运行,请改为抛出异常(确保添加适当的错误处理)。返回空值可能是可接受的情况,例如,尝试从数据库中获取对象。在这些情况下,编写处理空值的代码,并在您的耳朵后面记下,这里有可能返回空值的内容。处理返回的null值,使其尽可能接近返回null的方法的调用方(不要盲目地将其传递回调用链)永远不要将显式空值作为参数传递(至少不要跨类传递)。如果您曾经处于传递空参数是唯一选项的位置,那么创建一个不包含此参数的新方法是一种方法。验证您的输入!确定应用程序的“入口点”。它们可以从Web服务、REST服务、远程EJB类、控制器等所有内容。对于这些入口点中的每个方法,问问自己:“如果此参数为空,此方法是否正确执行?”如果答案为否,请添加Validate.notNull(someParam,“当someParam为空时无法运行!”);。如果缺少必需的参数,这将引发IllegalArgumentException。在入口点进行这种类型的验证的好处是,您可以很容易地在从入口点执行的代码中假设该变量永远不会为空!此外,如果这失败了,在入口点,调试会比代码深处出现NullPointerException要容易得多,因为这样的失败只能意味着一件事:客户端没有向您发送所有必需的信息。在大多数情况下,您希望验证所有输入参数,如果您发现自己处于需要允许大量空值的位置,这可能是接口设计不良的标志,需要进行重构/添加以满足客户机的需要。使用集合时,返回一个空集合而不是空集合!使用数据库时,请使用非空约束。这样,您就知道从数据库中读取的值不能为空,并且不必检查它。构造代码并坚持执行。这样做可以让您对代码的行为做出假设,例如,如果应用程序的所有输入都经过验证,那么您可以假设这些值永远不会为空。如果您还没有这样做,请编写代码的自动测试。通过编写测试,您将对代码进行推理,并且您也将更加确信它确实做到了它应该做的事情。此外,自动化测试通过让您立即知道这段代码没有做以前的事情来防止重构过程中的错误。

当然,您仍然需要进行空检查,但它可以降到最低限度(即,知道您可能会得到空值,而不是到处都是空值)。当谈到空检查时,我实际上更喜欢使用三元运算符(但要小心使用,当您开始嵌套它们时,它们会变得非常混乱)

public String nullSafeToString(final Object o) {
    return o != null ? o.toString() : "null";
}

对象.isNull(null)如果您使用的是Java8,则可以尝试此代码。

如果您不使用Java8,请尝试使用以下代码

Object ob=null;
if(ob==null){ **do something}

总而言之,避免声明

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)

函数方法可能有助于包装重复的空检查并执行匿名代码,如下面的示例。

    BiConsumer<Object, Consumer<Object>> consumeIfPresent  = (s,f) ->{
        if(s!=null) {
            f.accept(s);
        }
    };

    consumeIfPresent.accept(null, (s)-> System.out.println(s) );
    consumeIfPresent.accept("test", (s)-> System.out.println(s));

    BiFunction<Object, Function<Object,Object>,Object> executeIfPresent  = (a,b) ->{
        if(a!=null) {
            return b.apply(a);
        }
        return null;
    };
    executeIfPresent.apply(null, (s)-> {System.out.println(s);return s;} );
    executeIfPresent.apply("test", (s)-> {System.out.println(s);return s;} );

我们一直在使用Apache库(Apache Commons)解决这个问题。

ObjectUtils.equals(object, null)

or

CollectionUtils.isEmpty(myCollection);

or

StringUtils.isEmpty("string");

作为一种实践,我喜欢前面的回答,即为集合提供初始默认值或空集,以最小化需要。

这些可以是防止出现NullPointerException或使用空集合的简单用法。这并不能回答如何处理空对象的问题,但它们为对象或集合的基本验证提供了一些检查。

希望这有帮助。