这篇总结的形式是提出个问题,然后给出问题的答案。这是目前学习知识的一种尝试,可以让学习更有目的。
<强> Q1。强>
答:一般在我们需要进行值比较的时候,是需要重写对象的=方法的。而例外情况在《有效的java》的第7条”在改写=的时候请遵守通用约定”中清楚描述了。
我们知道,在Java中,每个对象都继承于对象。如果不重写,则默认的=代码如下所示:
公共布尔=(对象obj) { 返回这个==obj; } >之前由上面的代码可以看的出,等于默认是使用“==崩磁卸狭礁龆韵笫欠裣嗟取A礁龆韵笫褂谩?=北冉系氖嵌韵蟮牡刂?只有两个引用指向的对象相同的时候,“==辈欧祷卣返?所以,在开头的例子中,就需要重写=方法,让两个对象有平等的时候。
<强> Q2。强>
答:首先,当改写=方法时,需要保证满足它的通用约定。这些约定如下所示:
自反性,对于任意的引用值x, x.e quals (x)一定为真的。
对称性,对于任意的引用x和y值,当且仅当y.equals (x)时,x.e quals (y)也一定返回现实。
传递性,对于任意的引用值x, y, z。如果x.e quals (y)返回真,y.euqals (z)返回真,则x.e quals (z)也返回真的。
一致性,对于任意的引用x和y值,如果用于=比较的对象信息没有修改,那么,多次调用x.e quals (y)要么一致返回真,要么一致返回错误的。
非空性,所有的对象都必须不等于零。
其实我觉的一个简单的方法是参照字符串的=方法即可,官方出版,满足各种要求。其代码如下所示
公共布尔=(对象anObject) { 如果(这==anObject) { 返回true; } 如果(anObject instanceof字符串){ 字符串anotherString=(字符串)anObject; int n=计数; 如果(n==anotherString.count) { v1 char[]=价值; v2 char []=anotherString.value; int i=抵消; int j=anotherString.offset; 而(n - !=0) { 如果(v1 (+ +) !=v2 [j + +) 返回错误; } 返回true; } } 返回错误; } >之前函数的解释如下所示:
-
<李>使用==检查“实参是否是指向对象的一个引用”。李>
<李>使用instanceof检查实参是否和本对象同类,如果不同类,就不相等。李>
<李>将实参转换为正确的类型。李>
<李>根据类的定义,检查实现此对象值相等的各个条件。
李>
更详细的信息,还是请看《有效的java》的第7条”在改写=的时候请遵守通用约定”。
<强> Q3。强>
答:大致需要注意以下几点:
若修改=方法,也请修改hashCode方法
首先这个是语言的一个约定,这么做的一个原因是当此对象作为哈希容器的元素时,需要依赖hashCode、对象默认的hashCode是返回一个此对象特有的hashCode、不同的对象的hashCode返回值是不一样的,而哈希容器处理元素时,是按照对象的哈希值将对象分配到不同的桶中,若我们不重写对象的hashCode,那么值相等的对象产生的哈希值也会不同,这样当在哈希容器中查找时,会找不到对应的元素。
更详细的信息请看《有效的Java》的第8条“改写=时总是要改写hashCode”。
重写时保证函数声明的正确
请注意=的声明是
公共布尔=(对象obj) >之前参数类型是对象,如果参数类型是此对象类型的话,如下:
类点{ 最后一个int x; 最后一个int y; 公共空间点(int x, int y) 这一点。x=x; 这一点。y=y; } 公共布尔=(obj) { 返回(这。x==obj。x和,这一点。y==obj.y); } } >之前下面代码执行是按照我们的预期执行的。
点(1、2); Poinr b (1、2); System.out.println (a.equals (b));//输出真正的但是如果将类一个放入容器中,则会出问题
进口java.util.HashSet; HashSet科尔=new HashSet (); coll.add(一个); System.out.println (coll.contains (b));//输出假的 >之前 这是由于HashSet中的包含方法中调用的是=(对象obj),而点中的=(对象obj)仍是对象的=,这个方法在前面已经说过了,比较的是对象的地址,所以在胶原中调用包含(b)时,当然得不到真的。
Java中等于使用方法汇总