• 关于Integer类中Cache的解读


    我们以几道常见的面试题开头

     1 import org.junit.Test;
     2 
     3 public class Demo {
     4     private int num = 1;
     5 
     6     @Test
     7     public void test() {
     8         Integer x = 5;
     9         int y = 5;
    10         System.out.println(x == y); // true
    11 
    12         Integer i1 = 100;
    13         Integer i2 = 100;
    14         System.out.println(i1 == i2); // true
    15 
    16         Integer i3 = 128;
    17         Integer i4 = 128;
    18         System.out.println(i3 == i4); // false
    19     }
    20 }

     上面的代码中已经标明题目的答案,今天我将从字节码的角度解读为什么答案是那样的

    对于第一段代码

    1 Integer x = 5;
    2 int y = 5;
    3 System.out.println(x == y);

    这是这段代码所对应的字节码

     0 iconst_5
     1 invokestatic #3 <java/lang/Integer.valueOf>
     4 astore_1
     5 iconst_5
     6 istore_2
     7 getstatic #4 <java/lang/System.out>
    10 aload_1
    11 invokevirtual #5 <java/lang/Integer.intValue>
    14 iload_2
    15 if_icmpne 22 (+7)
    18 iconst_1
    19 goto 23 (+4)
    22 iconst_0
    23 invokevirtual #6 <java/io/PrintStream.println>
    26 return

    可以看出,在字节码的第一行,调用了Integer的静态方法valueOf(int),valueOf方法的目的是减少内存的负担,具体实现方法是,Integer类内部有一个Integer类型的cache数组用来存储[-128, 127]内的整数的Integer对象的引用,所以每当int类型自动装箱的时候,会调用Integer的valueOf方法,如果该数字在缓存范围内则直接返回该对象的引用,否则调用Integer的构造方法,创建一个新的对象

    在字节码第11行将 x 自动拆箱,然后与y进行比较

    对于第二段代码

    1 Integer i1 = 100;
    2 Integer i2 = 100;
    3 System.out.println(i1 == i2);

     其对应的字节码

    26 bipush 100
    28 invokestatic #3 <java/lang/Integer.valueOf>
    31 astore_3
    32 bipush 100
    34 invokestatic #3 <java/lang/Integer.valueOf>
    37 astore 4
    39 getstatic #4 <java/lang/System.out>
    42 aload_3
    43 aload 4
    45 if_acmpne 52 (+7)
    48 iconst_1
    49 goto 53 (+4)
    52 iconst_0
    53 invokevirtual #6 <java/io/PrintStream.println>

     可以看到字节码第28行和第34行,分别调用了Integer的静态方法valueOf,由于他们是相同对象的引用,因此在valueOf中返回的是同一个对象的引用,因此使用==判断地址后得到的是相同的值

    第三段代码同理,由于128不属于Integer的Cache范围,因此调用两次valueOf方法意味着生成了两个不同的对象,也就是说答案是false

  • 相关阅读:
    linux read的用法[转]
    1>/dev/null 2>&1的含义
    文件的权限
    【原创】server 10.192.242.184 not responding, still trying
    git使用中遇到的错误及解决方法
    linux中mmu作用的简单总结(未完)
    python版本设置
    【转】buntu TELNET服务安装配置
    【转】进程上下文和中断上下文、原子上下文的区别
    【转】【Linux】理解bitops中的__set_bit及其应用
  • 原文地址:https://www.cnblogs.com/bianjunting/p/13922944.html
Copyright © 2020-2023  润新知