Java中eqauls的原理
之前想查查==和equals的区别。老生长谈的东西了,网上查到的资料也有很多,但总有些不太明白,今天索性自己来一探究竟。
总结起来一句话:==只比较【原始类型的值】和【引用类型的栈内存地址值】是否相等。
那equals是怎么实现比较的呢?
先来看一下equals的代码是什么样子的:
equals()是每个对象与生俱来的方法,因为所有类的最终基类就是Object(除去Object本身);而equals()是Object的方法之一,也就是说equals()方法来自Object类。那么来看一下Object中怎么实现的equals:
public boolean equals(Object obj) {
return (this == obj);
}
这表示如果子类没有重写equals方法,那么执行该子类的equals方法就是直接将这两个对象引用进行比对,那比对的是什么呢?
“return (this == obj)” this与obj都是对象引用,而不是对象本身。所以equals()的缺省实现就是比较“对象引用”是否一致。即,比的是变量所拥有的“栈内存地址值”。说白了,就是==的作用。
那就是说,如果两个引用的不是同一个对象的话,那就不会相等。
可是,如果这样的话,那弄一个equals也没什么意义了,不如直接用==,还方便。所以,一般来讲,如果想要实现比较,都要自己实现equals这个方法。
下面是Double实现的equals方法:
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
可以看到,如果想要返回的结果是true,那么需要同时满足这样两个条件:
1.该对象是一个Double类型的实例。
2.满足1的条件下,比较两个Double对象(前一个是强制转换的,反正是Double的一个实例,不会出现问题)的value是否相同,如果相同的话,就可以返回true了。
明白了实现的源码之后就放心多了。来做一个简单的小题。
package com.bottle.test;
public class Bitch
{
public static void main(String[] args)
{
float f = 2.0f;
double d = 2.0;
Float F = new Float(2.0f);
Double D1 = new Double(2.0);
Double D2 = new Double(2.0);
printf("F==f:" + (F==f));
printf("D1==d:" + (D1==d));
printf("D1==f:" + (D1==f));
printf("D1.equals(d):" + (D1.equals(d)));
printf("D1.equals(D2):" + (D1.equals(D2)));
printf("D1.equals(f):" + (D1.equals(f)));
printf("D1.equals(F):" + (D1.equals(F)));
printf("F.equals(f):" + (F.equals(f)));
printf("F.equals(2.0):" + (F.equals(2.0)));
printf("F.equals(2.0f):" + (F.equals(2.0f)));
}
private static void printf(Object object)
{
System.out.println(object);
}
}
问:输出的结果是什么?
答案:
F==f:true
D1==d:true
D1==f:true
D1.equals(d):true
D1.equals(D2):true
D1.equals(f):false
D1.equals(F):false
F.equals(f):true
F.equals(2.0):false
F.equals(2.0f):true
本来想讲解一下,但觉得讲了不如自己琢磨的好,有不懂的同学可以多琢磨一会,想明白了,就会觉得,整个世界都安宁了。哈哈。