Java中Integer与int类型的装箱和拆箱

来源:互联网 发布:心事谁人知 黄乙玲 编辑:程序博客网 时间:2024/05/19 22:26

        其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
        我们分四种情况来讨论:
        1) Integer与int类型的赋值
                a.把Integer类型赋值给int类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
                b.把int类型赋值给Integer类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
        2) Integer与int类型的比较
                这里就无所谓是谁与谁比较了,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
        3) Integer之间的比较
                这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
        4) int之间的比较
                这个也一样,直接把两个变量的值进行比较。
        值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。底层代码如下:

    public static Integer valueOf(int i) {        assert IntegerCache.high >= 127;        if (i >= IntegerCache.low && i <= IntegerCache.high)            return IntegerCache.cache[i + (-IntegerCache.low)];        return new Integer(i);    }

        测试代码如下:

public class IntegerAndIntTest{public static void main(String[] args) throws Exception{Integer a = 127, b = 128;int c = 128;//自动装箱,这里会调用Integer中的valueOf方法把c装箱成Integer类型a = c;//这里比较的是两个对象的地址,显然不等System.out.println(a == b);//这里会调用Integer的intValue方法获得Integer对象a指向的栈地址中存的值再与c进行值比较,//而不是把c装箱成Integer类型进行地址比较System.out.println(a == c);//同上,也是获得a指向的栈地址中存的值System.out.println(c == a);/** * 总结:只有在赋值(=)的时候才会出现装箱和拆箱两种情况, * 在比较(==)的时候只会出现一种情况,那就是拆箱,而不会出现装箱的情况 */System.out.println("----------------------------------");Integer i1 = 127;Integer i2 = 127;System.err.println(i1 == i2);i1 = 128;i2 = 128;System.err.println(i1 == i2);/** * 总结:JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个; * 超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存,这样做是为了节省内存消耗。 */}}

        反编译结果:具体看第2、9、22、27、38、72、92、116、123、149、157等行,这几行涉及到装箱、拆箱。

  public static void main(java.lang.String[]) throws java.lang.Exception;    flags: ACC_PUBLIC, ACC_STATIC    Exceptions:      throws java.lang.Exception    Code:      stack=3, locals=7, args_size=1         0: bipush        127         2: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;         5: astore_1         6: sipush        128         9: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;        12: astore_2        13: sipush        128        16: istore_3        17: bipush        127        19: istore        4        21: iload_3        22: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;        25: astore_1        26: aload_1        27: invokevirtual #25                 // Method java/lang/Integer.intValue:()I        30: istore        4        32: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;        35: iload         4        37: aload_1        38: invokevirtual #25                 // Method java/lang/Integer.intValue:()I        41: if_icmpne     48        44: iconst_1        45: goto          49        48: iconst_0        49: invokevirtual #35                 // Method java/io/PrintStream.println:(Z)V        52: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;        55: aload_1        56: aload_2        57: if_acmpne     64        60: iconst_1        61: goto          65        64: iconst_0        65: invokevirtual #35                 // Method java/io/PrintStream.println:(Z)V        68: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;        71: aload_1        72: invokevirtual #25                 // Method java/lang/Integer.intValue:()I        75: iload_3        76: if_icmpne     83        79: iconst_1        80: goto          84        83: iconst_0        84: invokevirtual #35                 // Method java/io/PrintStream.println:(Z)V        87: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;        90: iload_3        91: aload_1        92: invokevirtual #25                 // Method java/lang/Integer.intValue:()I        95: if_icmpne     102        98: iconst_1        99: goto          103       102: iconst_0       103: invokevirtual #35                 // Method java/io/PrintStream.println:(Z)V       106: getstatic     #29                 // Field java/lang/System.out:Ljava/io/PrintStream;       109: ldc           #41                 // String ----------------------------------       111: invokevirtual #43                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V       114: bipush        127       116: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;       119: astore        5       121: bipush        127       123: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;       126: astore        6       128: getstatic     #46                 // Field java/lang/System.err:Ljava/io/PrintStream;       131: aload         5       133: aload         6       135: if_acmpne     142       138: iconst_1       139: goto          143       142: iconst_0       143: invokevirtual #35                 // Method java/io/PrintStream.println:(Z)V       146: sipush        128       149: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;       152: astore        5       154: sipush        128       157: invokestatic  #19                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;       160: astore        6       162: getstatic     #46                 // Field java/lang/System.err:Ljava/io/PrintStream;       165: aload         5       167: aload         6       169: if_acmpne     176       172: iconst_1       173: goto          177       176: iconst_0       177: invokevirtual #35                 // Method java/io/PrintStream.println:(Z)V       180: return


原创粉丝点击