我正在使用hibernate,需要重写equals和hashCode().我选择使用google-guava的equals和hashCode助手.
我想知道我是否在这里遗漏了一些东西.
我有idImage和filePath的get / set方法.
@Entity @Table(name = "IMAGE") public class ImageEntity { private Integer idImage; private String filePath; @Override public int hashCode() { return Objects.hashCode(getFilePath()); } @Override public boolean equals(final Object obj) { if(obj == this) return true; if(obj == null) return false; if(obj instanceof ImageEntity){ final ImageEntity otherImage = (ImageEntity) obj; return Objects.equal(getFilePath(),otherImage.getFilePath()); } return false; } }
编辑:
继承并拥有样本here
解决方法
instanceof运算符的问题是它可以考虑到多态性,如果我可以这么说.
比方说,你这样做:
public class AdvancedImageEntity extends ImageEntity { //some code here }
然后你这样做:
ImageEntity ie = new ImageEntity (); AdvancedImageEntity advanced_ie = new AdvancedImageEntity (); boolean this_will_be_true = ie.equals (advanced_ie);
顾名思义,等于call将返回true,因为instanceof运算符.
我知道这听起来像基本的东西,大多数人都知道,但是它很容易忘记它.现在,如果你想要这样的行为,那么很好,你实现的等于正确.但是,如果您认为ImageEntity对象不能等于(假设)AdvancedImageEntity对象,则声明ImageEntity为final或者忘记了instanceof并实现了这样的equals方法:
@Override public boolean equals(final Object obj) { if(obj == this) return true; if(obj == null) return false; if (getClass ().equals (obj.getClass ())) { final ImageEntity otherImage = (ImageEntity) obj; return Object.equals (getFilePath(),otherImage.getFilePath()); } return false; }
这将检查对象的真实类型,无论引用是什么类型.如果obj参数是一个子类的实例,它将通过instanceof“滑动”.但是getClass更加严格,不会允许.
PS:我不是说instanceof是坏的,不应该被使用.我只是说你必须意识到这个特殊情况,并决定是否考虑到这一点.