Java: чистый способ избежать исключения NullPointerException при проверке на равенство - PullRequest
20 голосов
/ 14 апреля 2011

У меня есть адресный объект, для которого я хочу создать метод 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 ]

15 голосов
/ 14 апреля 2011

Вы можете использовать вспомогательный метод, например

public static boolean isEqual(Object o1, Object o2) {
    return o1 == o2 || (o1 != null && o1.equals(o2));
}
8 голосов
/ 14 апреля 2011

Вы можете сделать следующее:

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, см .:

7 голосов
/ 14 апреля 2011

Google Guava предоставляет Objects.equal (Object, Object) , который проверяет равенство, учитывая, что любой из параметров может быть нулевым:

...
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 голосов
/ 14 апреля 2011

У меня есть вспомогательный класс 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());
1 голос
/ 14 апреля 2011

Нет действительно чистого способа сделать это;Наилучший вариант, вероятно, состоит в том, чтобы ваша IDE генерировала код для вас.Eclipse может сделать это через контекстное меню Source -> Generate hashCode () и equals ().

0 голосов
/ 14 апреля 2011

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();
0 голосов
/ 14 апреля 2011

Вы можете использовать Objects.equal из гуавы Googles или EqualsBuilder из общего доступа apache

0 голосов
/ 14 апреля 2011

Я бы рассмотрел определение некоторых методов equals как статических методов класса, как, например, для объектов Street. Таким образом, вы никогда не пытаетесь вызвать метод .equals () для нуля.

Пример функции может выглядеть следующим образом:

public static boolean equals(Object one, Object two)

Также рекомендуется ставить чеки типа

.
if (obj == null)
   return false;

в самом начале функции.

...