深入理解Java的整型类型:如何实现2+2=5?
先看下这段神奇的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虚拟机JVM】java如何实现跨平台
- 深入理解Java中的字符串类型
- Java Thread&Concurrency(10): 深入理解ThreadLocal及其实现原理
- Java Thread&Concurrency(8): 深入理解CompletionService接口及其实现
- Java Thread&Concurrency(12): 深入理解AbstractExecutorService及其实现原理
- Java Thread&Concurrency(2): 深入理解ConcurrentSkipListMap实现原理
- 深入理解JavaScript是如何实现继承的
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
- 孙鑫视频笔记之——深入理解多态是如何实现的
- Java Thread&Concurrency(16): 深入理解ArrayBlockingQueue及其实现原理
- Java Thread&Concurrency(11): 深入理解ThreadPoolExecutor及其实现原理
- 深入理解Java中的HashMap的实现原理
- [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
- 深入理解Java中的HashMap的实现机制
- Java Thread&Concurrency(14): 深入理解条件队列(Condition)及其实现原理
- JAVA NIO 新IO 分析 理解 深入 实例,如何利用JAVA NIO提升IO性能
- Java Thread&Concurrency(7): 深入理解Callable/Future(FutureTask)接口及其实现
- 深入理解JavaScript是如何实现继承的
- Java Thread&Concurrency(15): 深入理解ScheduledThreadPoolExecutor及其实现原理
- 深入理解JavaScript是如何实现继承的