继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

《手册》详解 第2节学员提问之 ==150问题解析

明明如月
关注TA
已关注
手记 59
粉丝 3858
获赞 1465

一、背景

码出规范:《阿里巴巴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 type Integer, then unboxing conversion converts r into r.intValue()

2.2 反汇编大法

假装我们不知道 JLS的规定,我们可以通过反汇编大法来查看。

http://img3.mukewang.com/5dc8322300014a9b07240438.jpg

核心逻辑:

看到行数为 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的整数对象,最后发现就一个。


http://img2.mukewang.com/5dc82639000114be12020690.jpg

因此第二个 150并没有转成整数对象。

建议大家可以掌握这种查看内存对象的方法,当没有声明引用时无法通过变量窗口查看时,可以采用此方法核实。

专栏后续的代码调试小节将讲述如异常断点,远程调试等更多调试技巧。

三、总结

1 通过《《手册》详解 第2节学员提问之断点 i=255问题解析 》 和本小节,大家可以发现,记忆知识容易遗忘,而方法才是通用的,掌握常见的经典的好方法可以用来解决很多同类的问题。

2 希望大家以后可以养成分析问题的习惯,遇到类似问题时可以快速解决,而不是搜索各种博客,询问别人。

希望大家能够自主学习,知其然又知其所以然。

3 专栏还会介绍更多学习和排错技巧,感兴趣的同学可以关注专栏。购买链接:https://s.imooc.com/WP71m6k


相关文章

1Integer 缓存问题分析

2《手册》详解 第2节学员提问之断点 i=255问题解析 





打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP