直接看测试
定义两个Long对象
public static void main(String[] args) {
Long left = 100L;
Long right = 100L;
if(left == right){
System.out.println("left == right");
}else{
System.out.println("left != right");
}
}
//Output:left == right
将两个Long对象的值变一下,
public static void main(String[] args) {
Long left = 200L;
Long right = 200L;
if(left == right){
System.out.println("left == right");
}else{
System.out.println("left != right");
}
}
OutPut:left != right
经过循环测试得出的结果是:[-128,127] 这个区间的Long是相等的,但区间外是非等的。等等,这个区间好像是short类型的范围吧,莫非有什么关联?拭目以待!
这是什么原因?
这就要提及到 == 和 equals 的区别了
1)== 永远比较的是内存地址,是比较两个对象在内存中的地址
2)equals是java.lang.Object类中的一个方法,java中所有的类都默认继承Object,equals 是比较两个对象的内容(堆中的内容)
Long是包装类,是long的包装,是一个对象,
下面这段时Long对象的源码
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
所以两个Long类型的变量进行比较的话,要么使用equals()方法
要么就先调用longValue()方法拿到Long对象里面的long值再进行比较。
说到这,好像还没有说为什么Long对象在区间 [-128,127] 之间为什么相等?好的,扯远了,言归正传,回归主题。
网上很多人说这和jdk的打包拆包有关,对于小白的我来说,自动拆箱/装箱跟我有关系吗?反正我又不懂
在翻阅大量内容找到了这么一段底层代码
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
在128~127这些数的对象在内存中被缓存起来,在内存中提供重用,这些数获取的时候就会自动获取缓存中的数,而不是new出来的对象。
所以,判读Long对象是否相等的时候建议不要采用 == 的形式,程序中无法绝对的判断参数值是否会在这个区间内,如果不在,那就出现让你摸不着头脑的问题。
其他包装类的有趣现象
Double
public class Main {
public static void main(String[] args) {
Double d1 = 100.0;
Double d2 = 100.0;
Double d3 = 200.0;
Double d4 = 200.0;
System.out.println(d1==d2);
System.out.println(d3==d4);
}
}
OutPut:
false
false
是不是有点大跌眼镜的感觉(起初我也是的),准备吃饭的我,又坐在了电脑前,为了寻求真理我饭都不吃了(此处给自己奖励一个女朋友,new girlFriend())
在女朋友的帮助下,我在此进行简单的解释:
Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
看来是这 七 种包装类是分家了啊(不对,怎么少了一个!敢做逃兵,杀无赦!!!!!!!!!)
我:黑白无常,我命你二人(不对,是二鬼)将Boolean给我捉拿归案
黑白无常:厉鬼勾魂,无常索命
Boolean:大人,小的冤枉啊,小的一直在家中酣睡,并为逃离。
Boolean的辩词
public class Main {
public static void main(String[] args) {
Boolean b1 = false;
Boolean b2 = false;
Boolean b3 = true;
Boolean b4 = true;
System.out.println(b1==b2);
System.out.println(b3==b4);
}
}
OutPut:
true
true
Boolean:大人,这足以证明小的和他们不是一家的,因此大人在它们家是看不到小人的,小的冤枉啊。
我:就算是我冤枉了你!那你说,为什么你自成一家?有何原因?速速道来!!!!!
Boolean:
下面是我的valueOf方法的具体实现:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
下面是我的两个儿子,也就是程序员口中的两个静态成员属性
public static final Boolean TRUE = new Boolean(true);
/**
* The <code>Boolean</code> object corresponding to the primitive
* value <code>false</code>.
*/
public static final Boolean FALSE = new Boolean(false);
我:什么乱七八糟的,本官听不懂,拉出去,打二十大板,在此期间本官要好好研究一下Boolean刚才说的话
结局:Boolean没能扛住二十大板的威力,在冤枉中死去。
三天后
我:想想Boolean临死前三天所说的话,我依然一头迷雾,哎,算了吧。你们自己思考吧!!!!!