|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
Java到底会发战成什么样,让我们拭目以待吧,我始终坚信着java会更好。以上都是俺个人看法,欢迎大家一起交流.
译者注:你大概会以为Java很复杂,Object的equals完成也会十分复杂,可是现实并非你设想的如许,耐烦的读完本文,你会发明你对Java懂得的是云云的少。假如这篇文章是一份Java程序员的进职口试,那末不晓得有几人会失落落到如许的圈套中。
择要
本文形貌重载equals办法的手艺,这类手艺即便是具现类的子类增添了字段也能包管equal语义的准确性。
在《EffectiveJava》的第8项中,JoshBloch形貌了当承继类作为面向对象言语中的等价干系的基本成绩,要包管派生类的equal准确性语义所会晤对的坚苦。Bloch如许写到:
除非你健忘了面向对象笼统的优点,不然在当你承继一个新类或在类中增添了一个值组件时你没法同时包管equal的语义仍然准确
在《ProgramminginScala》中的第28章演示了一种办法,这类办法同意即便承继了新类,增添了新的值组件,equal的语义仍旧能失掉包管。固然在这本书中这项手艺是在利用Scala类情况中,可是这项手艺一样能够使用于Java界说的类中。在本文中的形貌来自于ProgramminginScala中的笔墨形貌,可是代码被我从scala翻译成了Java
罕见的等价办法圈套
java.lang.Object类界说了equals这个办法,它的子类能够经由过程重载来掩盖它。不幸的是,在面向对象中写出准确的equals办法长短常坚苦的。现实上,在研讨了大批的Java代码后,2007paper的作者得出了以下的一个结论:
几近一切的equals办法的完成都是毛病的!
这个成绩是由于等价是和良多其他的事物相干联。比方个中之一,一个的范例C的毛病等价办法大概意味着你没法将这个范例C的对象可托赖的放进到容器中。好比说,你有两个元素elem1和elem2他们都是范例C的对象,而且他们是相称,即elem1.equals(elm2)前往ture。可是,只需这个equals办法是毛病的完成,那末你就有大概会瞥见以下的一些举动:
SethashSet<C>=newjava.util.HashSet<C>();
hashSet.add(elem1);
hashSet.contains(elem2); //returnsfalse!
当equals重载时,这里有4个会激发equals举动纷歧致的罕见圈套:
界说了毛病的equals办法署名(signature)Definingequalswiththewrongsignature.
重载了equals的但没有同时重载hashCode的办法。ChangingequalswithoutalsochanginghashCode.
创建在会变更字域上的equals界说。Definingequalsintermsofmutablefields.
不满意等价干系的equals毛病界说Failingtodefineequalsasanequivalencerelation.
在剩下的章节中我们将顺次会商这4中圈套。
圈套1:界说毛病equals办法署名(signature)
思索为上面这个复杂类Point增添一个等价性办法:
publicclassPoint{
privatefinalintx;
privatefinalinty;
publicPoint(intx,inty){
this.x=x;
this.y=y;
}
publicintgetX(){
returnx;
}
publicintgetY(){
returny;
}
//...
}
<p>
在ruby里才是一切皆对象。当然我不并不是很了解ruby,但是ruby确实是将语法简化得很好。 |
|