Java:在equals检查中避免NullPointerException的干净方法

时间:2011-04-14 10:35:50

标签: java nullpointerexception equals coding-style

我有一个地址对象,我想为其创建一个equals方法。我可以通过做类似下面的事情(缩短一点)来使这变得非常简单:

public boolean equals(Object obj) 
{
    if (this == obj)
        return true;

    if (obj == null)
        return false;

    if (getClass() != obj.getClass())
        return false;

    Address other = (Address) obj;

    return this.getStreet().equals(other.getStreet())
        && this.getStreetNumber().equals(other.getStreetNumber())
        && this.getStreetLetter().equals(other.getStreetLetter())
        && this.getTown().equals(other.getTown());
}

问题是,其中一些可能为空。换句话说,如果此地址中没有街道字母,我将获得NullPointerException

如何在考虑空值的情况下以干净的方式写这个?

8 个答案:

答案 0 :(得分:15)

您可以使用辅助方法,例如

public static boolean isEqual(Object o1, Object o2) {
    return o1 == o2 || (o1 != null && o1.equals(o2));
}

答案 1 :(得分:8)

您可以执行以下操作:

public boolean equals(Object obj) 
{
    if (this == obj) {
        return true;
    }

    if (obj == null) {
        return false;
    }

    if (getClass() != obj.getClass()) {
        return false;
    }

    Address other = (Address) obj;

    return equals(this.getStreet(),other.getStreet())
        && equals(this.getStreetNumber(), other.getStreetNumber())
        && equals(this.getStreetLetter(), other.getStreetLetter())
        && equals(this.getTown(), other.getTown());
}

private boolean equals(Object control, Object test) {
    if(null == control) {
        return null == test;
    }
    return control.equals(test);
}

Java 7引入了对java.util.Objects类的用例的内置支持,请参阅:

答案 2 :(得分:7)

Google Guava提供Objects.equal(Object, Object),它会检查是否相等,同时考虑到其中一个参数可能为null:

...
return Objects.equal(this.getStreet(), other.getStreet())
    && Objects.equal(this.getStreetNumber(), other.getStreetNumber())
    && Objects.equal(this.getStreetLetter(), other.getStreetLetter())
    && Objects.equal(this.getTown(), other.getTown());

值得指出的是,Objects还有其他辅助方法来实现hashCode()toString()

答案 3 :(得分:3)

我有一个带有静态方法的助手类Checker:

 public static boolean isEquals(final Object o1, final Object o2) {
        return o1 == null ? o2 == null : o1.equals(o2);
 }

所以,在equals方法中,

 return Checker.isEquals(this.getStreet(), other.getStreet())
        && Checker.isEquals(this.getStreetNumber(), other.getStreetNumber())
        && Checker.isEquals(this.getStreetLetter(), other.getStreetLetter())
        && Checker.isEquals(this.getTown(), other.getTown());

答案 4 :(得分:1)

没有真正干净的方法可以做到这一点;最好的选择可能是让IDE为您生成代码。 Eclipse可以通过Source来实现 - >生成hashCode()和equals()上下文菜单。

答案 5 :(得分:0)

我会考虑将一些equals方法定义为静态类方法,比如说对于Street对象。这样你就不会尝试在null上调用.equals()方法。

示例函数可能如下所示:

public static boolean equals(Object one, Object two)

此外,最好放一些像

这样的支票
if (obj == null)
   return false;

在函数的最开始。

答案 6 :(得分:0)

您可以使用Googles guava中的Objects.equal或来自apache commons的EqualsBuilder

答案 7 :(得分:0)

Apache Commons Lang为等式比较提供EqualsBuilder帮助程序类。哈希码也有一个。

return new EqualsBuilder()
.append(this.getStreet(), other.getStreet())
.append(this.getStreetNumber(), other.getStreetNumber()
.append(this.getStreetLetter(), other.getStreetLetter())
.append(this.getTown(), other.getTown())).isEquals();