先看下这段神奇的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. vue-router 基本知识点

    vue-router就是将组件映射到路由,然后告诉vue-router在哪里渲染它们. 默认路由出口 <router-view></router-view> 使用router- ...

  2. CentOS下安装SecureCRT的sz/rz工具包

    对于使用SecureCRT的玩家,rzsz是一个灰常灰常实用的功能.但是定制安装的linux可能没有把rzsz包安装到系统,这对用securecrt这样的windows工具传输文件特别不方便.为了使用 ...

  3. https://www.luogu.org/blog/An-Amazing-Blog/mu-bi-wu-si-fan-yan-ji-ge-ji-miao-di-dong-xi

    https://www.luogu.org/blog/An-Amazing-Blog/mu-bi-wu-si-fan-yan-ji-ge-ji-miao-di-dong-xi

  4. hihoCoder 1032

    最长回文子串的O(1)算法Manacher算法 #include <iostream> #include <stdio.h> #include <string.h> ...

  5. python help(int)

    class int(object) | int(x=0) -> integer | int(x, base=10) -> integer | | Convert a number or s ...

  6. bzoj 3027: [Ceoi2004]Sweet【生成函数+组合数学】

    首先根据生成函数的套路,这个可以写成: \[ \prod_{i=1}^{n}(1+x^1+x^2+...+x^{c[i]}) \] 然后化简 \[ =\prod_{i=1}^{n}\frac{1-x^ ...

  7. P5161 WD与数列(后缀自动机+线段树合并)

    传送门 没想出来→_→ 首先不难看出要差分之后计算不相交也不相邻的相等子串对数,于是差分之后建SAM,在parent树上用线段树合并维护endpos集合,然后用启发式合并维护一个节点对另一个节点的贡献 ...

  8. IT兄弟连 JavaWeb教程 URI、URL

    URI介绍 URI(Uniform Resource Identifier),是统一资源标识符的缩写,是一个用于标识某一个Web资源名称的字符串,该标识允许用户对任何资源通过特定的协议进行交互.Web ...

  9. 在 React项目中使用 bootstrap

    在使用create-react-app 创建的项目中使用 bootstrap; 安装react-bootstrap; npm install react-bootstrap --savenpm ins ...

  10. 项目中java异常处理

    一.java异常类介绍. Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类. 有一篇比较好的blog ...