聊聊JavaScript和Scala的表达式 Expression
先看下这段神奇的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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
深入理解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里面的代码...
- 下一篇
Golang学习笔记-IDE安装指南
引言 上篇Golang学习笔记-环境搭建指南已经讲解了如何搭建Golang开发环境,并写了一个Go程序【Hello,world】,但是写代码没有一个好用的IDE,没有语法高亮,自动补全,格式调整,查找函数等功能,想必也会令大家抓狂吧,笔者以前是做Java和.Net开发的,经常用的IDE有Eclipse、IntelliJ IDEA和Visual Studio,其中Eclipse和IntelliJ IDEA能安装很多插件,自然想到是否能在Eclipse和IntelliJ IDEA上安装支持Go语言开发的插件,搜一下插件还真有,废话不多说,直接进入IDE安装过程吧。 IntelliJ IDEA安装Go语言插件 首先你的安装好IntelliJ IDEA,具体安装过程这里不表,不懂请百度,笔者的IDEA版本是2017.1.5 IDEA Version 点击【File】-【Settings】 menu 选择【Plugins】-【Install JetBrains plugin…】 install plugins 输入【go】,选择【Go Languages】,然后点击【Install】,需...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境