先看下这段神奇的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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

最新文章

  1. JavaScript - 正则表达之二
  2. 我的sql 记录
  3. 新安装个Myeclipse,导入以前做的程序后程序里好多错,提示The import java.util cannot be resolved
  4. HDU 4471 矩阵快速幂 Homework
  5. notepad++必读
  6. 自动检查点(Automatic Checkpointing)
  7. 关于datatable转换datatime类型的问题
  8. 字符编码:ANSI,ASCII,GB2312,GBK,Big5,Unicode和UTF-8
  9. [Locked] Zigzag Iterator
  10. 判断input checkbox选中状态
  11. C语言,调试必备的DEBUG宏定义
  12. Android 中内容提供者的使用
  13. ubuntu15.10 opencv3.1 安装配置codeblocks
  14. js禁止页面滚动
  15. node.js中使用yargs来处理命令行参数
  16. 基于hiredis,redis C客户端封装
  17. (2)The secrets of learning a new language
  18. phpize增加php模块
  19. STM32 & FreeRTOS & KFIFO (巧夺天工)
  20. UDP接收数据

热门文章

  1. cmake官方文档
  2. robotframework之APP混合H5自动化测试
  3. 一个不当使用fclose引发的异常
  4. 004--linux命令tar 软硬链接
  5. git stash和git stash pop(转载)
  6. 用script标签加载
  7. bzoj 1488: [HNOI2009]图的同构【polya定理+dfs】
  8. Nginx(四) nginx+consul+upasync 在ubnutu18带桌面系统 实现动态负载均衡
  9. Five things that make Go fast-渣渣翻译-让GO语言更快的5个原因
  10. 跟我一起玩Win32开发(8):绘图(A)