Long == Long 的有趣现象


直接看测试
定义两个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临死前三天所说的话,我依然一头迷雾,哎,算了吧。你们自己思考吧!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值