先看下这段神奇的Java代码:

public static void main(String[] args) throws Exception {

      doSomethingMagic();

      System.out.printf("2 + 2 = %d", 2 + 2);

}

执行结果:2 + 2 = 5

那么doSomethingMagic到底做了什么神奇的事情呢?先看代码:

private static void doSomethingMagic() throws Exception {

   Class cache = Integer.class.getDeclaredClasses()[0];

   Field c = cache.getDeclaredField("cache");

   c.setAccessible(true);

   Integer[] array = (Integer[]) c.get(cache);

   array[132] = array[133];

}

所以这个例子其实包含了Java中整型类型Integer的一个知识点。

可能有的朋友对于doSomethingMagic里面的代码有点摸不着头脑,让我们先查看上图第17行 2 + 2反编译出来的代码:

编辑器将2+ 2的值先计算出来,等于4。最后System.out.println打印出来的值,实际上是Integer.valueOf(4)的返回值。

那么我们就查看JDK里Integer.valueOf的实现:

上面的实现代码,从830行到832行,逻辑非常清楚:如果valueOf的参数i在IntegerCache.low和IntegerCache.high之间,即[-128, 127]的闭区间,则直接从IntegerCache这个缓存区域里返回。只有当输入参数i不在[-128,127]区间内,才执行代码832,基于输入参数i创建一个新的Integer实例。

带着这个理念,我们再看doSomethingMagic就清楚多了。这个方法通过Java反射将上图IntegerCache的成员cache设置成可访问:setAccessible(true), 然后将IntegerCache的第132个元素的值用第133个元素的值覆盖。

我们从Eclipse调试器里发现,Integer cache里第132个元素的值为4,第133个元素的值为5。本来Integer.valueOf方法,对于输入4,从Integer cache里返回第132个元素的值,即4。现在这个元素的值被第133个元素即5覆盖了,所以最后得到了 2 + 2 = 5。

用一句话概括这个场景: 2 + 2 = 4 = Integer.valueOf(4) = 5 ( 因为4在Integer cache里对应的记录已经被我们的代码显式替换成了5)。

要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

深入理解Java的整型类型:如何实现2+2=5?的更多相关文章

  1. JAVA 长整型转换为IP地址的方法

    JAVA 长整型转换为IP地址的方法 代码例如以下: /** * 整型解析为IP地址 * @param num * @return */ public static String int2iP(Lon ...

  2. (转)JAVA的整型与字符串相互转换

    JAVA的整型与字符串相互转换1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或         ...

  3. java中大整型BigInteger及setBit和testBit方法

    最近在修改公司之前的项目,在项目中遇到了权限校验的问题,代码中出现了BigInteger的setBit()testBit()方法,之前未接触过,所以了解了下BigInteger. 在Java中,由CP ...

  4. 零基础如何学好Python 之int 数字整型类型 定义int()范围大小转换

    本文主题是讲python数字类型python int整型使用方法及技巧.它是不可变数据类型中的一种,它的一些性质和字符串是一样的,注意是整型不是整形哦. Python int有多种数字类型:整型int ...

  5. 理解Java中的字符串类型

    1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和w ...

  6. 深入理解java中的byte类型

    作者 | 进击的石头--GO! 来源 | https://www.cnblogs.com/zl181015/p/9435035.html#4432849 Java也提供了一个byte数据类型,并且是基 ...

  7. golang的数据类型之整型类型

    数据类型: 整数 : int, int32, int64, uint, uint32, uint64 字符串 : string 布尔:bool 浮点:float32 float64 uint 表示无符 ...

  8. Java关于整型类缓存[-128,127]之间的数字

    我们在学习Java的包装类Integer.Long的时候可能会遇到这个问题: ①Integer a = 500;// Integer a = Integer.valueOf(500); 等价于上面的 ...

  9. JAVA的整型与字符串相互转换

    1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([S ...

随机推荐

  1. python中list用法及遍历删除元素

    列表(list)是python的基本数据结构,list中每一个元素都分配一个位置索引,可以通过索引访问元素值,list不要求数据项有相同的数据类型. list初始化 list由一个方括号加内部由逗号分 ...

  2. BZOJ_1406_[AHOI2007]密码箱_枚举+数学

    BZOJ_1406_[AHOI2007]密码箱_枚举+数学 Description 在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能破解密码就能打开箱子,而箱子 ...

  3. noip数学

    一.取模运算 (1)定义 给定一个正整数p和一个整数n 一定存在此等式 n=k*p+r;其中k,r是整数,r大于等于0小于p 称k是n除以p的商,r为n除以p的余数 说明:同余式 正整数a,b对p取模 ...

  4. Laravel 5.4 中的异常处理器和HTTP异常处理实例教程

    错误和异常是处理程序开发中不可回避的议题,在本地开发中我们往往希望能捕获程序抛出的异常并将其显示打印出来,以便直观的知道程序在哪里出了问题并予以解决,而在线上环境我们不希望将程序错误或异常显示在浏览器 ...

  5. (bmp格式)用CDialog的OnCtlColor()消息响应处理背景画刷。

    (bmp格式)用CDialog的OnCtlColor()消息响应处理背景画刷. 加载位图资源IDB_BITMAP1,在Dlg类头文件中加入: CBrush m_brush; 在OnInitDialog ...

  6. fileupload简单使用

    form.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" page ...

  7. Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)

    题目链接: Hdu 5446 Unknown Treasure 题目描述: 就是有n个苹果,要选出来m个,问有多少种选法?还有k个素数,p1,p2,p3,...pk,结果对lcm(p1,p2,p3.. ...

  8. WOJ1109 奶牛排队

    题目链接: WOJ1109 题目描述: 奶牛在熊大妈的带领下排成了一条直队. 显然,不同的奶牛身高不一定相同-- 现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛A是最矮的,最右边的B是最 ...

  9. Easy Game LightOJ - 1031

    Easy Game LightOJ - 1031 upd:似乎有复杂度更优越的做法,见http://www.cnblogs.com/hehe54321/p/8431020.html 题意:A和B玩一个 ...

  10. Varnish快速安装及测试

    实验环境: slave-147:   192.168.75.147 slave-148:    192.168.75.148 两台机器均已关闭selinux,关闭iptables. varnish部署 ...