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

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

当前回答

哇,当我们有57种不同的方式来推荐NullObject模式时,我几乎不想再加一个答案,但我想,一些对这个问题感兴趣的人可能想知道,有人提议为Java7添加“空安全处理”,这是一种精简的语法,如果不等于空逻辑的话。

Alex Miller给出的示例如下:

public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  

这个表示仅在左标识符不为空时取消引用,否则将表达式的其余部分求值为空。一些人,如Java Pose成员迪克·沃尔(Dick Wall)和德文郡的选民,真的很喜欢这个提议,但也有人反对,理由是它实际上会鼓励更多地使用null作为前哨值。


更新:在Project Coin下提交了一份关于Java 7中空安全运算符的官方提案。语法与上面的示例稍有不同,但概念相同。


更新:空安全运营商提议未纳入Project Coin。因此,您不会在Java7中看到这种语法。

其他回答

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

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

这是大多数开发人员最常见的错误。

我们有很多方法来处理这个问题。

方法1:

org.apache.commons.lang.Validate //using apache framework

notNull(对象对象,字符串消息)

方法2:

if(someObject!=null){ // simply checking against null
}

方法3:

@isNull @Nullable  // using annotation based validation

方法4:

// by writing static method and calling it across whereever we needed to check the validation

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

首先,我们不能真正删除所有空条件。我们可以使用@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);

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

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

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

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

现在来回答:

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

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

字节