non*_*tor 3 java performance equals
在我写完标题之后,我读了这篇SO 帖子,但仍然决定在Java中讨论有关bug的bug实现问题.这是我的正常实施
@Override
public boolean equals(Object o){
if(o == null) return false;
if(o instanceof CompositePk == false) return false;
if(this == o) return true;
CompositePk that = (CompositePk)o;
return new EqualsBuilder().append(this.id, that.id)
.append(this.bucketId, that.bucketId)
.isEquals();
}
Run Code Online (Sandbox Code Playgroud)
使用Apache的EqualsBuilder来完成平凡的事情.比这更容易的是我的Netbean自动生成的equals(o)实现
@Override
public boolean equals(Object obj){
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TemplatesWrapper other = (TemplatesWrapper) obj;
if (this.timeAdded != other.timeAdded && (this.timeAdded == null || !this.timeAdded.equals(other.timeAdded))) {
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
我从2个差异项目中获取这些,但他们都试图完成同样的事情,但使用diff方法.您认为哪种风格或者您发现有什么缺陷?
首先,有没有需要测试null,然后测试的instanceof,因为foo instanceof Bar计算结果为false,当foo为null.
instanceof比较运算符的结果很奇怪false,因为它instanceof是一个布尔运算.
比较课程getClass()充其量是有争议的.约书亚布洛赫,谁写的Java集合框架和很多其他重要的东西之外的多,说:
这种技术("基于getClass的等于方法")确实满足了等于合同,但成本很高.getClass方法的缺点是它违反了"Liskov替换原则",该原则(粗略地说)指出一个超类实例的方法在呈现子类实例时必须正常运行.如果子类添加了一些新方法,或者简单地修改了行为(例如,通过在每次方法调用时发出跟踪),当子类和超类实例不能正确交互时,程序员会感到惊讶."应该是平等的"对象不会,导致程序失败或行为不规律.Java的集合基于equals方法,这个问题更加严重.
除非您有某些特定的技术原因,否则您应该使用instanceof而不是比较via getClass().
在确定另一个对象可比较之后this,然后将基元与==对象进行比较equals.如果您的任何成员对象可以为null,则会更复杂; 然后你必须编写详细的子句来比较可能的null事物(或写一个bothNullOrEqual(Object a, Object b)方法).
这种EqualsBuilder方法看起来很虚伪,但这只是一种"气味",我不会在技术上反对.一般来说,我不喜欢可能经常调用的方法中的额外方法调用.
Apache的一个是假的,因为它测试null并使用getClass()比较.
这是我的:
@Override
public boolean equals(final Object o) {
if (!(o instanceof MyClass))
return false;
final MyClass om = (MyClass)o;
// compare om's fields to mine
}
Run Code Online (Sandbox Code Playgroud)
我会这样做:
public boolean equals(Object ob) {
if (ob == null) return false;
if (ob == this) return true;
if (!(ob instanceof MyClass)) return false; // OR
if (ob.getClass() != getClass()) return false;
// check relevant members
}
Run Code Online (Sandbox Code Playgroud)
中间的两条线是不同的.一个允许子类相等(第一个),另一个不允许.使用合适的任何一种.
举个例子,Java的AbstractList类可能会使用第二种形式,因为确切的实现List是无关紧要的.重要的是,如果成员是平等的,并且处于相同的位置.
相反,Person类应该使用第一个表单(instanceof),因为如果有一个Student子类并且你调用Person.equals(Student)它可以返回true而不检查Student中的额外字段,而Student.equals(Person)可能会返回false.如果equals()不是可交换的,那你就是在寻找麻烦.
我倾向于使用equals()我的IDE(IntelliJ IDEA)生成的方法,而不是为某些Apache库创建不必要的依赖,以获得很少的收益.
| 归档时间: |
|
| 查看次数: |
8343 次 |
| 最近记录: |