博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解Java的整型类型:如何实现2+2=5?
阅读量:5845 次
发布时间:2019-06-18

本文共 1303 字,大约阅读时间需要 4 分钟。

hot3.png

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

转载于:https://my.oschina.net/u/3771578/blog/2250142

你可能感兴趣的文章
理解 Linux 配置文件【转】
查看>>
在C#中使用消息队列RabbitMQ
查看>>
Basic Tutorials of Redis(8) -Transaction
查看>>
DIV向上滚动(类似新闻)
查看>>
学习PHP的必备开发工具
查看>>
快速幂矩阵小结
查看>>
pythonGUI-wxpython
查看>>
精妙SQL语句集合
查看>>
最小生成树模板 加 例题分析 (最小生成树类型汇总)
查看>>
pdf.js跨域加载文件
查看>>
对比jQuery和AngularJS的不同思维模式
查看>>
遮盖效果
查看>>
国外著名数学杂志
查看>>
CSS自定义消息提示
查看>>
JSP PO VO BO DTO POJO DAO解释
查看>>
KitKat带来短信应用的改变
查看>>
零值比较
查看>>
web渗透测试中WAF绕过讲解(二)基于HTTP协议绕过
查看>>
【CSON原创】CSS的障眼法:利用border实现图片的翻转
查看>>
oracle:plsql学习总结(oracle database 10g sql 开发指南)
查看>>