一、背景
码出规范:《阿里巴巴Java开发手册》详解专栏刚发布, 其中 “第二节 02 Integer缓存问题分析”讲到:
Integer var = ? 形式声明整型,最终会通过 java.lang.Integer#valueOf(int) 来构造整数对象。
有一个学员提出了断点时出现 i =255问题,在另外一篇文章作了分析:https://www.imooc.com/article/294578
又有一个朋友发了另外一个类似的问题:
public static void main(String[] args) { Integer c = 150; System.out.println(c==150); }
相信学过本专栏的同学可以快速解决这个问题。
二、问题分析
2.1 JLS 大法
根据 JLS 可知,整数对象和整数数值通过 == 比较时,会自动拆箱,比较的是数值。
If
r
is a reference of typeInteger
, then unboxing conversion convertsr
into
r
.intValue()
2.2 反汇编大法
假装我们不知道 JLS的规定,我们可以通过反汇编大法来查看。
核心逻辑:
看到行数为 17的地方,将 intValue 和 150 整数值比较,如果不相等跳转到 24行,
24行将常量0入栈 (虚拟机中用0 可以表示false),然后调用参数为 boolean类型(Z)的打印语句打印,。
如果相等,继续执行到20行,将常量1入栈,然后调用参数为 boolean类型(Z)的打印语句。
反向翻译成 Java源代码大致如下:
public static void main(String[] args) { Integer c = 150; if(c.intValue() == 150){ System.out.println(true); }else{ System.out.println(false); } }
因此答案就非常显而易见了。
在这里希望大家能够自主学习 《Java虚拟机规范》,反汇编后能够有自行脑补出对应的Java代码的能力。
Java语言手册和虚拟机手册官方版下载:https://docs.oracle.com/javase/specs/index.html
大家如果看英文吃力,也可以自行购买中文翻译版。
2.3 代码调试法
我们可以在构造方法上和valueOf上打断点,看看来自自己源码调用时 参数为150的调用有几次,可以观察到只有一次。
另外我们还可以查看内存中构造的值为 150的整数对象个数。
可以从右下角的 memory 选项卡中搜索 Integer ,然后双击后使用表达式 equals(150)来查看,值为 150的整数对象,最后发现就一个。
因此第二个 150并没有转成整数对象。
建议大家可以掌握这种查看内存对象的方法,当没有声明引用时无法通过变量窗口查看时,可以采用此方法核实。
专栏后续的代码调试小节将讲述如异常断点,远程调试等更多调试技巧。
三、总结
1 通过《《手册》详解 第2节学员提问之断点 i=255问题解析 》 和本小节,大家可以发现,记忆知识容易遗忘,而方法才是通用的,掌握常见的经典的好方法可以用来解决很多同类的问题。
2 希望大家以后可以养成分析问题的习惯,遇到类似问题时可以快速解决,而不是搜索各种博客,询问别人。
希望大家能够自主学习,知其然又知其所以然。
3 专栏还会介绍更多学习和排错技巧,感兴趣的同学可以关注专栏。购买链接:https://s.imooc.com/WP71m6k
相关文章
共同学习,写下你的评论
评论加载中...
作者其他优质文章