Java: Clean way of avoiding NullPointerException in equals checks

前端 未结 8 1549
感情败类
感情败类 2021-02-12 12:27

I have an address object that I want to create an equals method for. I could have made this quite simple by doing something like the following (shortened a bit):



        
相关标签:
8条回答
  • 2021-02-12 12:37

    You can use a helper method like

    public static boolean isEqual(Object o1, Object o2) {
        return o1 == o2 || (o1 != null && o1.equals(o2));
    }
    
    0 讨论(0)
  • 2021-02-12 12:41

    I'd consider defining some of the equals methods as static class methods, like say for the Street objects. This way you don't ever attempt to call the .equals() method on a null.

    A sample function might look like:

    public static boolean equals(Object one, Object two)
    

    Also, it's good practice to put checks like

    if (obj == null)
       return false;
    

    at the very beginning of a function.

    0 讨论(0)
  • 2021-02-12 12:42

    Google Guava provides Objects.equal(Object, Object) which checks for equality while taking into consideration that either of the parameters might be 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());
    

    It's also worth pointing out that Objects has other helper methods for implementing hashCode() and toString().

    0 讨论(0)
  • 2021-02-12 12:45

    I have a helper class Checker w/ a static method:

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

    so, in the equals method,

     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());
    
    0 讨论(0)
  • 2021-02-12 12:46

    You could do the following:

    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 introduced built-in support for this use case with the java.util.Objects class see:

    • java.utils.Objects.equals(Object, Object)
    • java.utils.Objects.deepEquals(Object, Object)
    0 讨论(0)
  • 2021-02-12 12:56

    Apache Commons Lang provides the EqualsBuilder helper class for equality comparissons. There is also one for hash codes.

    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 讨论(0)
提交回复
热议问题