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

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

当前回答

我尝试过NullObjectPattern,但对我来说并不总是最好的方法。有时,“不采取行动”并不合适。

NullPointerException是一个运行时异常,这意味着它是开发人员的错,并且凭借足够的经验,它会准确地告诉您错误在哪里。

现在来回答:

尽量将所有属性及其访问器设为私有,或者避免将它们暴露给客户端。当然,您可以在构造函数中设置参数值,但通过缩小范围,您不会让客户端类传递无效值。如果需要修改值,可以始终创建新对象。您只检查构造函数中的值一次,在其他方法中,您几乎可以确定这些值不为空。

当然,经验是理解和应用这一建议的更好方式。

字节

其他回答

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

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

例如

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

有一种很好的方法来检查JDK中的空值。Optional.java有大量解决这些问题的方法。例如:

    /**
     * Returns an {@code Optional} describing the specified value, if non-null,
     * otherwise returns an empty {@code Optional}.
     *
     * @param <T> the class of the value
     * @param value the possibly-null value to describe
     * @return an {@code Optional} with a present value if the specified value
     * is non-null, otherwise an empty {@code Optional}
     */
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    /**
     * Return {@code true} if there is a value present, otherwise {@code false}.
     *
     * @return {@code true} if there is a value present, otherwise {@code false}
     */
    public boolean isPresent() {
        return value != null;
    }
    /**
     * If a value is present, invoke the specified consumer with the value,
     * otherwise do nothing.
     *
     * @param consumer block to be executed if a value is present
     * @throws NullPointerException if value is present and {@code consumer} is
     * null
     */
    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

帮助标枪真的非常非常有用。

只是永远不要使用null。不要允许。

在我的类中,大多数字段和局部变量都有非空的默认值,我在代码中的任何地方都添加了契约语句(总是在断言上),以确保这是强制执行的(因为它比让它作为NPE出现然后必须解析行号等更简洁、更具表达力)。

一旦我采用了这种做法,我注意到问题似乎会自行解决。你会在开发过程中很早就发现事情,只是偶然发现自己有一个弱点。。更重要的是。。它有助于封装不同模块的关注点,不同模块可以相互“信任”,不再在代码中添加if=nullelse结构!

这是一种防御性编程,从长远来看,代码会更加干净。始终对数据进行净化,例如在这里通过强制执行严格的标准,问题就会消失。

class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}

合同就像是小型单元测试,即使在生产中也始终在运行,当事情失败时,你知道原因,而不是随机的NPE,你必须设法弄清楚。

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

ObjectUtils.equals(object, null)

or

CollectionUtils.isEmpty(myCollection);

or

StringUtils.isEmpty("string");

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

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

希望这有帮助。

具有零安全性的Kotlin是一种优雅的选择,但它意味着更大的变化。