正确的实施方式等于合同

che*_*ine 18 java

我有一个名为User的域对象.用户的属性包括ssoId,name,email,createdBy,createdDate和userRole.其中,ssoId必须是唯一的,因为没有两个用户可以拥有相同的sso id.所以我的equals方法检查sso id并返回true或false.

@Override public boolean equals(Object o) {
    if (!(o instanceof User))
      return false;
    return user.getSsoId().equals((User)o.getSsoId());
}
Run Code Online (Sandbox Code Playgroud)

我觉得这是一个不正确的实现,尽管就业务规则而言是正确的.对于具有相同sso id但具有不同的名称或电子邮件或两者的值的两个对象,上述实现将返回true.我应该更改我的平等合同以检查所有字段的相等性吗?你的建议是什么?

Bal*_*usC 17

这对于"技术平等"(几乎)是正确的,但不是"自然平等".要实现最高技术平等,您还应该测试反身o == this.可能会发生该对象尚未持久保存在DB中,因此尚未拥有技术ID.例如

public class User {

    private Long id;

    @Override
    public boolean equals(Object object) {
        return (object instanceof User) && (id != null) 
             ? id.equals(((User) object).id) 
             : (object == this);
    }

    @Override
    public int hashCode() {
        return (id != null)
             ? (User.class.hashCode() + id.hashCode())
             : super.hashCode();
    }

}
Run Code Online (Sandbox Code Playgroud)

对于"自然平等",您应该比较所有非技术属性.对于"现实世界的实体"而言,这比技术平等更加强大(但也更昂贵).

public class User {

    private String name;
    private Date birth;
    private int housenumber;
    private long phonenumber;

    @Override
    public boolean equals(Object object) {
        // Basic checks.
        if (object == this) return true;
        if (!(object instanceof User)) return false;

        // Property checks.
        User other = (User) object;
        return Objects.equals(name, other.name)
            && Objects.equals(birth, other.birth)
            && (housenumber == other.housenumber)
            && (phonenumber == other.phonenumber);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, birth, housenumber, phonenumber);
    }

}
Run Code Online (Sandbox Code Playgroud)

是的,当有很多属性时,那就是很多代码.有点像样的IDE(Eclipse中,NetBeans中,等),可以只自动生成equals(),hashCode()(也toString(),getter和setter)为您服务.利用它.在Eclipse中,右键单击代码并查看Source(Alt + Shift + S)菜单选项.

也可以看看: