下面我们来分析,上篇博客中遗留的问题,为什么下方的两个一个是true,两一个是false那?

//true
Long l1=123l;
Long l2=123l;
System.out.println(l1==l2);
//false
Long l1=123456l;
Long l2=123456l;
System.out.println(l1==l2);

在上面的代码中,是把字面量赋值给了一个引用类型,在一般情况下这是不被允许的,但java中有自动装箱/自动拆箱的概念,导致了上面的赋值操作正常运行,也就是对于8种基本数据类型,都有对应的包装类,byte、short、int、long、float、double、char、boolean对应的包装类分别是Bytes、Short、Integer、Long、Float、Double、Character、Boolean。在Long l1=123l这行代码中就发生了自动装箱,即l1这个变量是引用类型的,其值为字面量。也就是l1、l2、l3、l4都为对象,那么使用==比较符比较的时候比较的肯定是内存地址,为什么一个true,一个false那。因为缓存,在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);
}
}

可以看到LongCache静态内部类中,存在一个容量为256的Long类型的静态数组,其值的范围为-128~127。自动装箱的过程就像Long中的valueOf方法的过程如下,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的范围间,如果要生产Long类型的对象,那么返回的是LongCache类中cache数组中的元素,而cache数组在类加载的时候已经初始化完毕(缓存),所以只要是在-128~127间的数据,不论多少个对象,返回的都是同一个对象,对同一个对象使用==比较符比较的时候肯定返回的是true,对于不在-128~127间的数就不是这个样子了。

这样就解释了开头中一个为true,一个为falsle的原因。

对于其他的包装类:Integer、Short、Character、Bytes等内部也有缓存类,但Integer缓存类中有high属性,可以设置缓存的最大范围(最小为-128)。

参考:java中整型的缓存机制

感谢,有问题欢迎指正!

equals和==方法比较(三)--Long中LongCache源码分析的更多相关文章

  1. 【原】Spark中Client源码分析(二)

    继续前一篇的内容.前一篇内容为: Spark中Client源码分析(一)http://www.cnblogs.com/yourarebest/p/5313006.html DriverClient中的 ...

  2. 【原】Spark中Master源码分析(二)

    继续上一篇的内容.上一篇的内容为: Spark中Master源码分析(一) http://www.cnblogs.com/yourarebest/p/5312965.html 4.receive方法, ...

  3. 【原】 Spark中Worker源码分析(二)

    继续前一篇的内容.前一篇内容为: Spark中Worker源码分析(一)http://www.cnblogs.com/yourarebest/p/5300202.html 4.receive方法, r ...

  4. php中foreach源码分析(编译原理)

    php中foreach源码分析(编译原理) 一.总结 编译原理(lex and yacc)的知识 二.php中foreach源码分析 foreach是PHP中很常用的一个用作数组循环的控制语句.因为它 ...

  5. 手把手教你实现栈以及C#中Stack源码分析

    定义 栈又名堆栈,是一种操作受限的线性表,仅能在表尾进行插入和删除操作. 它的特点是先进后出,就好比我们往桶里面放盘子,放的时候都是从下往上一个一个放(入栈),取的时候只能从上往下一个一个取(出栈), ...

  6. Java中ArrayList源码分析

    一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保 ...

  7. Java中HashMap源码分析

    一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...

  8. 动态代理以及对应Spring中AOP源码分析

    AOP(面向切面编程)在Spring中是被广泛应用的(例如日志,事务,权限等),而它的基本原理便是动态代理. 我们知道动态代理有两种:基于JDK的动态代理以及基于CGlib动态代理.以下是两种动态代理 ...

  9. [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)

    对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...

随机推荐

  1. css注入获取网页中的数据

    <style><?php echo htmlspecialchars($_GET['x']);?></style> <br><br>< ...

  2. Windows命令行使用总结(持续更新)

    1. 根据端口号查找进程: netstat -ano | findstr "port" 2. 获取任务列表: tasklist 3. 如果我们想要结束某个程序的所有进程的话,比如, ...

  3. CTreeCtrl::HitTest

    CTreeCtrl::HitTest   调用此函数确定指定的位置点相对树视图控件的工作区的. HTREEITEM HitTest(  CPoint pt,  UINT* pFlags = NULL  ...

  4. 什么是Spring框架? Spring框架有哪些主要的模块?

    Spring框架是一个为java应用程序的开发提供了综合,广泛的基础性支持的java平台.Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发.Spring框架本身亦是 ...

  5. 纸质文稿如何生成PDF

    步骤: (1) 将即将要转换的文稿单张向下放入打印机. (2) 将打印设备(打印机)连接至你的电脑. (3) 打开控制面板,点击"查看设备和打印机". (4) 找到你当前的打印设备 ...

  6. iOS之oc与html之间的交互(oc中调用js的方法)

    一.运行的效果图 1.刚开始的效果   2.运行结束后的效果   二.准备工作 1.准备一个html文件导入到oc工程中 2.jiaohu.html文件的原始内容   3.从oc语言中操作.html文 ...

  7. 设计一个学生类&班级类

    第一题 设计一个学生类 属性:姓名.学号.年龄.成绩 设计一个班级类要求:实现向班级中添加学生.删除学生.查看学生.按照指定条件排序 属性:班级代号,所有学生 需要使用 calss, __int__, ...

  8. 帝国CMS给会员注册加入问答验证

    修改文件有e/enews/index.php //注册 elseif($enews=="register") { if($_POST['ask']=='帝国软件') { $user ...

  9. Alluxio原理和应用场景随笔

    上周末有幸参加了Alluxio(之前也叫Tachyon),七牛云和示说网举办的Alluxio上海Meetup,之前我并没有在真实应用场景中使用过Alluxio,对其适用的应用场景一直报怀疑态度.自信聆 ...

  10. 一图看懂JVM,JRE,JDK的关系