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

一、背景

码出规范:《阿里巴巴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问题解析 

发布了379 篇原创文章 · 获赞 862 · 访问量 132万+

猜你喜欢

转载自blog.csdn.net/w605283073/article/details/103003854