Java:全部的equals办法实现都是错误的?[Java编程]
本文“Java:全部的equals办法实现都是错误的?[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
本文介绍了一种改写(override)equals 办法的本领.利用该本领,即便在实体类的子类增添了新的域(field)时,仍旧可以满意 equals 办法的约定.
在《Effective Java》一书的第 8 条目中,Josh Bloch 将子类化时满意 equals 约定这一艰难描写为:面向对象语言中等值关系的最根本问题.Bloch 这样写道:
不存在一种方法,可以在扩大非实例类并增添值组件的同时,仍旧满意equals的约定.除非你乐意放弃面向对象的抽象性这一长处.
《Programming in Scala》一书中的第 28 章供应了一种办法,子类可以对非实例类举行扩大,增添值组件,而同时满意 equals 约定.固然书中供应的那种本领是用于定义 Scala 类,但一样实用于 Java 中的 类定义.在本文中,为了讲授这种办法,我将利用《Programming in Scala》中相关章节,改编相关的文本,并将原书中的 Scala 示例代码转换为了 Java 代码.
常见的等值陷阱
Class java.lang.Object 定义了一个 equals 办法,此中的子类可以举行改写(override).不幸的是,终究的后果表明,在面向对象语言中,编写精确的等值办法相当艰难.事实上,在对 Java 代码的大量正文举行研究之后,几位作者在 2007 年的一份论文中作出以下结论:几近全部 equals 办法的实现都是错误的.
这是一个严重的问题,因为等值办法是很多代码的根本.其一,关于范例 C,一个错误的等值办法大概意味着,你不能坚固地将一个范例 C 的对象放入调集合.你大概有两个等值的范例 C 元素 elem1、elem2,即“em1.equals(elem2)”输出 true.但是,在下面的示例中,equals 办法的实现就是一种常见的错误:
Set< C> hashSet = new java.util.HashSet< C>();
hashSet.add(elem1);
hashSet.contains(elem2); // 返回 false!
存在四种常见的陷阱,它们城市在改写equals时招致非一致性的行为:
◆利用错误的原型对equals举行定义.
◆更改equals而未同时更改 hashCode.
◆对equals举行定义时触及可变域(field).
◆未能成功地将equals定义为等值关系.
这四种陷阱将在下文中具体报告.
陷阱 1:利用错误的原型对equals举行定义
在下面的代码中,我们将为普通点的类增添一个等值办法:
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
// ...
}
以上是“Java:全部的equals办法实现都是错误的?[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |