天天看点

Integer类自动装箱、拆箱与享元模式

       从JDK1.5开始java添加了一个新特性:自动装箱和拆箱。这极大的简化了简单类型与包装类型之间的转换,那么自动装箱和拆箱是怎么实现的呢?

现来看一行源代码:

Integer a = 125;

用javap工具查看其字节码为:

    0:  bipush  125

    2:  invokestatic  #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

     5:  astore_1

    可以发现Integer类的自动装箱是通过调用类的静态方法valueOf实现的。

阅读Integer类的源代码发现该类还用到了享元模式,对于范围在-128~127的int类型数,不是新创建一个对象,而是返回内存中已有的对象,对于不在此范围里的数则新创建一个对象。可以看一段代码:

    Integer a = 125;

    Integer b = 125;

    System.out.println(a == b);

    Integer a1 = 128;

    Integer b1 = 128;

    System.out.println(a1 == b1);

输出是:

true

false

这是怎么实现的呢?

原因就在于在Integer类里有个内隐类IntegerCache,存放-128~127范围内的对应Integer类对象。

该类的静态方法valueOf的实现是当数在此范围之内时直接返回内隐类IntegerCache中存放的对应的Integer类对象,否则用new新生成一个对象。这个就是设计模式中的享元模式吧。

那自动拆箱呢?

也先来看两行代码:

int b = a;

其字节码指令为:

     0:  bipush  125

     2:  invokestatic  #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

     6:  aload_1

     7:  invokevirtual  #22; //Method java/lang/Integer.intValue:()I

     10:  istore_2

     11:  return

可以看到自动拆箱是调用Integer类的成员方法intValue()实现的,而intValue方法就一行语句”返回其value值。

继续阅读