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

我有一个地址对象,我想为其创建一个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

如何在考虑空值的情况下以干净的方式编写此文件?

您可以使用辅助方法

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

您可以执行以下操作:

 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类的用例的内置支持,请参阅:

  • java.utils.Objects.equals(Object,Object)
  • java.utils.Objects.deepEquals(Object,Object)

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() 。

我有一个带有静态方法的助手类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()); 

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

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

示例函数可能如下所示:

 public static boolean equals(Object one, Object two) 

此外,最好将支票放入

 if (obj == null) return false; 

在函数的最开始。

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

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();