Long与Integer的总结

前言:
一直以为包装类和String有相似的地方,直到遇到了一些代码的输出结果和自己所想不同,才发现需要去仔细的研究一下包装类的性质。主要的内容是参考收集的资料。

问题

Long与Ineger都是包装类型,是对象。而不是普通类型long与int , 所以它们在比较时必须都应该用equals,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的。但是有一种特殊情况, 其实Long与Integer都将 -128~127 这些对象缓存了。 可以看看Long类型源码里面有一个LongCache类,代码如下:

private static class LongCache {  
    private LongCache(){}  

    static final Long cache[] = new Long[-(-128) + 127 + 1];  

    static {  
        for(int i = 0; i < cache.length; i++)  
        cache[i] = new Long(i - 128);  
    }  
} 

例子代码

public class Test05 {  
    public static void main(String[] args) {  
        Long a = 5L;  
        Long b = 5L;  
        System.out.println("a == b ? " + (a == b));  

        Long c = 129L;  
        Long d = 129L;  
        System.out.println("c == d ? " + (c == d));  
    }  
} 

打印结果:
a == b ? true
c == d ? false

原因
首先来看看 Long a = 5L ; 它是如何将一个基本类型long包装成一个对象Long的 。可以写一个测试类,然后反编译一下,看看java它是如何解析Long a = 5L这样一条命令的。
测试类如下:
public class Test06 {
Long l = 3L;
}
然后使用javap -verbose Test06 就能看到反编译的结果了, 下面是输出的部分:

{  
java.lang.Long l;  

public com.spring.test.Test06();  
  Code:  
   Stack=3, Locals=1, Args_size=1  
   0:   aload_0  
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V  
   4:   aload_0  
   5:   ldc2_w  #12; //long 3l  
   8:   invokestatic    #14; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;  
   11:  putfield        #20; //Field l:Ljava/lang/Long;  
   14:  return  
  LineNumberTable:  
   line 3: 0  
   line 5: 4  
   line 3: 14  

  LocalVariableTable:  
   Start  Length  Slot  Name   Signature  
   0      15      0    this       Lcom/spring/test/Test06;  
}  

从Code中的8可以看出调用了Long的一个类方法Long.valueOf(Long) , 所以可以得到的结论是Long a = 5L实际上等于 Long a = Long.valueOf(5) ;
然后再看看Long.valueOf()方法是如何定义的:

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之间,就会直接从LongCache里面取出缓存的对象返回,否则就new一个新的Long对象返回 。
现在就不难理解Test05程序执行得到的结果了,因为a与b等于5,在-127~128之内,所以都是直接从LongCache里面返回的一个Long对象,所以他们在使用==比较的时候,就是相等的(对于对象类型来说,==比较的是两个对象的引用指向堆中的地址) ,而c与d等于129,不在-127~128之间,所以他们他们是分别new出来的两个新的Long对象,使用==来比较自然是不相等的了。
Long重写了equals方法

 public boolean equals(Object obj) {  
    if (obj instanceof Long) {  
        return value == ((Long)obj).longValue();  
    }  
    return false;  
}  

参考博客:http://blog.csdn.net/is_zhoufeng/article/details/38443507

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
integerlong之间的转换方法有多种。首先,可以使用类型强制转换将long转换为int。例如,可以使用以下代码将long类型的变量numberLong转换为int类型的变量numberInt:int numberInt = (int) numberLong。\[1\] 另一种方法是使用Long的API。可以使用numberLong.intValue()将Long类型的变量numberLong转换为Integer类型的变量intNumber。\[2\] 还可以利用String进行转换。可以使用numberLong.toString()将Long类型的变量numberLong转换为String类型的变量strValue,然后使用Integer.valueOf(strValue)将String类型的变量strValue转换为Integer类型的变量intValue。\[2\] 将Integer转换为Long也有几种方法。首先,可以使用类型强制转换,但这种方法不可用。\[3\]另一种方法是使用BigDecimal进行强制转换。可以使用BigDecimal的构造函数或BigDecimal.valueOf()方法将int类型的变量numberInt转换为BigDecimal类型的变量bigNumber,然后使用bigNumber.longValue()将BigDecimal类型的变量bigNumber转换为long类型的变量numberLong。\[3\] 总结起来,integerlong之间的转换可以使用类型强制转换、Long的API或BigDecimal进行转换。具体使用哪种方法取决于具体的需求和代码实现。 #### 引用[.reference_title] - *1* *2* *3* [LongInteger相互转换](https://blog.csdn.net/weixin_44712778/article/details/128671276)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值