一、背景
码出规范:《阿里巴巴Java开发手册》详解 专栏刚发布, 其中 “第二节 02 Integer缓存问题分析”讲到:
Integer var = ? 形式声明整型,最终会通过 java.lang.Integer#valueOf(int) 来构造整数对象。
有一个学员提出了断点时出现 i =255问题,在另外一篇文章作了分析:https://dwz.cn/m1of2kIu
又有一个朋友发了另外一个类似的问题:
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的规定,我们可以通过反汇编大法来查看。
public class com.imooc.basic.learn_int.IntegerTest {
public com.imooc.basic.learn_int.IntegerTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: sipush 150
3: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
6: astore_1
7: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
10: aload_1
11: invokevirtual #4 // Method java/lang/Integer.intValue:()I
14: sipush 150
17: if_icmpne 24
20: iconst_1
21: goto 25
24: iconst_0
25: invokevirtual #5 // Method java/io/PrintStream.println:(Z)V
28: return
}
核心逻辑:
看到行数为 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://dwz.cn/2GIxxC9n
相关文章
1Integer 缓存问题分析
2《手册》详解 第2节学员提问之断点 i=255问题解析