- 浏览: 250283 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
aquarion:
非常感谢,解决了我的问题
Perspective 自定义设置扩展点 -
zheng_zhen:
好文章,进一步问您一下,请问自己实现的run/debug如何能 ...
【原创】Eclipse Launcher (Run/Debug As 菜单扩展)实现 -
salever:
mwdnjupt 写道http://www.xeclipse. ...
浅析OSGI的bundle依赖 -
mwdnjupt:
http://www.xeclipse.com/?p=1165 ...
浅析OSGI的bundle依赖 -
Tom.X:
插件化、模块化应遵循高内聚、低耦合的原则,尽量不要在各bund ...
浅析OSGI的bundle依赖
equals 方法在非空对象引用上实现相等关系:
自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。
另请参见:
hashCode(), Hashtable
我们先来看看Object中equals的实现:
public boolean equals(Object obj) { return (this == obj); }
当且仅当两个对象是同一个时,equals才返回true,这个实现当然满足以上的自反性、对称性、传递性、一致性。然而在绝大多数情况下,这个默认实现都不好用,用户往往需要重写这个方法。一旦重写了这个方法,很可能潜在的破坏了以上约束,给程序带来潜在威胁。
看一个Effective java中给出的一个违反对称性的例子:
/** * Case-insensitive string. Case of the original string is preserved by * toString, but ignored in comparisons. */ public final class CaseInsensitiveString { private String s; public CaseInsensitiveString(String s) { if (s == null) throw new NullPointerException(); this.s = s; } // Broken - violates symmetry! public boolean equals(Object o) { if (o instanceof CaseInsensitiveString) return s.equalsIgnoreCase(((CaseInsensitiveString) o).s); if (o instanceof String) // One-way interoperability! return s.equalsIgnoreCase((String) o); return false; } // Remainder omitted }
这个实现对于
CaseInsensitiveString cis = new CaseInsensitiveString("Polish"); String s = "polish";
cis.equals(s) 为true,而s.equals(cis) 为false。如果出现下面的代码,结果是什么呢?
List list = new ArrayList(); list.add(cis); list.contains(s) = ?
到底list.contains(s)返回true还是false,这就说不清了。按照目前的JVM实现,这个是false。
一个可能的实现为:
public boolean equals(Object o) { return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); }
再看一个违反传递性的例子:
public class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Point)) return false; Point p = (Point) o; return p.x == x && p.y == y; } } public class ColorPoint extends Point { private Color color; public ColorPoint(int x, int y, Color color) { super(x, y); this.color = color; } // Broken - violates transitivity. public boolean equals(Object o) { if (!(o instanceof Point)) return false; // If o is a normal Point, do a color-blind comparison if (!(o instanceof ColorPoint)) return o.equals(this); // o is a ColorPoint; do a full comparison ColorPoint cp = (ColorPoint) o; return super.equals(o) && cp.color == color; } }
根据上面的实现
ColorPoint p1 = new ColorPoint(1, 2, Color.RED); Point p2 = new Point(1, 2); ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
p1.equals(p2) = ture && p2.equals(p3) = true,而p1.equals(p3) = false,原因很简单,在
if (!(o instanceof ColorPoint)) return o.equals(this);
这里出了问题,当o为Point时,调用了Point的equals(),忽略了color属性,从而使得p1.equals(p2)&&p2.equals(p3),一个可能的实现为
// Adds an aspect without violating the equals contract public class ColorPoint { private Point point; private Color color; public ColorPoint(int x, int y, Color color) { point = new Point(x, y); this.color = color; } /** * Returns the point-view of this color point. */ public Point asPoint() { return point; } public boolean equals(Object o) { if (!(o instanceof ColorPoint)) return false; ColorPoint cp = (ColorPoint)o; return cp.point.equals(point) && cp.color.equals(color); } ... // Remainder omitted }
在重写扩展基类的equals方法时,最好放弃使用继承,而采取组成的方式,将基类作为一个成员属性,这样可以避免由继承带来的各种问题。There is simply no way to extend an instantiable class with a new aspect while preserving the compareTo contract。如果你想扩展一个已经实现了equals的类,不要去继承它,而是在类中使用一个它的实例对象作为成员。
接下来讲讲 == 操作符与equals()的关系。== 比较两个对象时,返回true意味着两个对象是同一个。在Object的默认实现中,== 与equals就是一回事,也就是
Object obj1, obj2;
obj1.equals(obj2) 与obj1 == obj2 是一样的效果,
但是要注意在obj1、obj2都为null时,前者会抛出异常而后者则返回true。
Object obj1 = null, obj2 = null; if(obj1 == obj2){ System.out.println("true"); }else{ System.out.println("false"); } if(obj1.equals(obj2)){ System.out.println("true"); }else{ System.out.println("false"); } }
输出为:
Exception in thread "main" java.lang.NullPointerException
参考文档:
1,《Efficient Java》 Joshua Bloch
2, J2sk 6.0 API
发表评论
-
Java 技能树
2016-07-25 18:58 726java技能树 -
Java看书笔记
2014-08-07 17:15 696这一篇专用于一些日常的Java读书笔记 先写一点关 ... -
XStream和Jackson的使用优化
2012-12-17 11:09 0marker一下,需要研究一下这2种lib的使用方式。 -
ArrayList与LinkedList的简单比较
2012-07-27 11:07 1490本文同步发表在http://www.xeclipse.com/ ... -
java.lang.System类浅析
2012-07-25 09:58 1859本文同步发表在 http://www.xeclipse.com ... -
Linux/Unix下JFreeChart的NoClassDefFoundError问题
2012-07-04 14:51 1633最近遇到这样一个问题,使用JFreechart 1.0.13开 ... -
【转】常见的开源协议
2011-08-12 15:47 485Mozilla Public License ... -
【转】JDK发布版本时间以及代号
2011-06-20 14:02 1507已发行的版本: 版本号 名称 中文名 发布日期 ... -
最近的apache学习计划
2011-06-09 11:58 1194最近可能会要做一些apache相关的学习和开发工作,有一些pr ... -
Object类wait,notify,notifyAll的使用
2011-05-06 11:02 1434这三个方法是java的基础类Object中定义的。 w ... -
Java nio 整理整理
2011-02-25 17:17 1076看了看Java的nio类库,整理一下思路。 1,Buf ... -
Java 内存的那些事
2011-02-22 10:38 4944虽然Java屏蔽了一下内存 ... -
一些有用的Web Service 地址
2011-02-11 11:11 2175这里记录一下比较有用的Web Service 地址,可能会有用 ... -
【Java】利用HTML生成PDF之问题整理
2011-01-06 14:38 3829首先,技术为apache 的FOP ... -
【转】如何在java程序中设置文件为“隐藏”属性
2010-10-19 10:55 1564引自http://linshiquan.iteye.com/b ... -
【转】字符,字节和编码
2010-10-18 10:09 1146引言 “字符与编码” ... -
Effective Java 第2版 笔记
2010-08-18 15:45 1779Item 1;Consider static factoriy ... -
Java, 那些美妙的书籍
2010-08-10 15:39 7180整理一下最近看过或者比较有兴趣的Java书籍,以供大家参考 ... -
Object的equals()与hashCode()的关系
2010-08-10 14:37 0笔者在以前Java项目中使用findbugs工具时,经常遇到一 ... -
学习JVM 之 class文件校验器
2010-07-21 11:29 1942JVM中的class文件校 ...
相关推荐
面试官瞬间就饱了,重写equals函数,需要重写hashCode函数吗? 面试官问我,为什么重写equals函数,必须重写hashCode函数,我当时就懵住了。 然后扯天扯地,然后面试官瞬间就饱了,痛定思痛,写下这篇博客 首先看...
首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法
Object类是所有Java类的根类,它定义了一些常用的方法,例如equals()、hashCode()、toString()等。本案例代码将详细展示Object类的使用方法,并提供一些实际场景下的案例,以帮助开发者更好地理解和运用这些方法。 ...
equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值。 hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类Object的hashCode()方法的...
Object 类是所有类的父类,其 equals 方法比较的是两个对象的引用指向的地址,hashcode 是一个本地方法,返回的是对象地址值。他们都是通过比较地址来比较对象是否相等的
前言 对于开发的程序员小伙伴,...equals:在Object中模式采用==比较,通常会重写 String对象重写了 equals,比较的是变量值 从上面我们笼统的来说明了一下两者的不同,那么接下来我们看看具体的区分 对象类型的比较
equals(父类是object,所以每个对象都会有equals): ojbect的 (源代码的149行):出厂默认的话equals等价于 == string 类重写equals:比较的是每一个字符是否相等 hashCode(重写equals就一定要重写hashCode...
个人学习终结成果:为什么要重新equals和hashCode方法?如何重写?站好马步需从j2se基础开始
Object类的 equals() 方法直接用 == 实现,不适用!! ! 所以,通常override(重写/覆写)java.lang.0bject 类的中equals()方法 按照自己的需要,在equals()方法中定义对象相等的含义。 String.equals () 注意:当此...
而Object的派生类ValueTpye重写了Equals方法,它比较的是两个对象的逻辑等同性。 也就是说,在C#里,引用类型的默认Equals版本关注的是引用等同性,而值类型关注的是逻辑等同性。当然,这并不总能
hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。 使用hashCode()和equals() hashCode()方法被用来获取给定对象的整数。这个整数被用来确定对象被...
要求覆盖基类Object中的ToString()方法和Equals()方法,使得直接输出Student对象时输出的是对象的id,name和age信息;并且当两个对象的学号相同时认为它们相等; 然后写一个主方法测试以上定义。
为什么重写 equals() 时必须重写 hashCode() 方法? String String、StringBuffer、StringBuilder 的区别? String 为什么是不可变的? 字符串拼接用“+” 还是 StringBuilder? String#equals() 和 Object#equals() ...
主要介绍了Java中的Object类详细介绍,本文讲解了Object类的作用、Object类的主要方法、Object类中不能被重写的方法、Object类的equals方法重写实例等内容,需要的朋友可以参考下
==与equals的比较,包装类的使用
提供了20道高难度的Java Object类面试题及详细答案解析,涵盖了equals()、hashCode()、toString()、clone()、finalize()等方法的重写和应用,以及对象的比较、克隆、标识哈希码等概念。适合准备Java面试的开发者深入...
C#中判断两个对象是否相等有Equals、RefrenceEquals和==三种,其中==为运算符,其它两个为方法,而Equals又有两种版本,一个是静态的,一个是虚拟的,虚拟的可以被实体类重写,静态的在方法体内也是调用虚拟的,如下...
如果不是想使用object类,toString方法,可以重写此方法 equals方法 equals方法比较对象的是否相同 ==比较两个对象的内存地址 如果想表示对象的内容相同,返回true,则重写此方法 hashCode 返回一个hash code码,...
equals是Object类的方法,Object对它的实现是比较内存地址,我们可以重写这个方法来自定义“相等”这个概念。比如类库中的String、Date等类就对这个方法进行了重写。综上,对于枚举类型和原始数据类型的相等性比较,...
然后需要重写 Equals 方法。 public override bool Equals(object obj) { if (!obj.GetType().Equals(typeof(Customer))) { return false; } else { Customer answer = (Customer)obj; return (answer.ID ==...