Java 自动拆箱装箱

自动拆箱及装箱

Java为每种基本数据(char,byte,short,int,long,float,double)

设置了装箱方法:valueOf()拆箱方法:typeValue()

除了floatdouble外,每种类型同时设立了Cache,此种设计加快了创建变量的效率以及减少内存的占用。

自动拆箱装箱的实现

public static void main(String[] args) {
    Integer a = 1, b = 2, c = 3, d = 3;
    System.out.println(c == d);          // true
    System.out.println(c == (a + b));    // true
    System.out.println(c.equals(a + b)); // true
}
复制代码

将上边的代码进行反编译可得下方的JVM指令,通过line: 1, 6, 11, 16我们可以观察到,装箱时会自动调用对应类型的装箱方法valueOf()

line: 42 ~ 50我们可以看出,当两个数相加时,首先调用拆箱方法intValue(),随后将得到的值再次进行装箱a + b = 3此时进行装箱得到结果3,仍处于cache范围中,因此c == (a + b)仍然为true

public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: invokestatic  #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       4: astore_1
       5: iconst_2
       6: invokestatic  #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       9: astore_2
      10: iconst_3
      11: invokestatic  #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: astore_3
      15: iconst_3
      16: invokestatic  #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      19: astore        4
      21: getstatic     #3 // Field java/lang/System.out:Ljava/io/PrintStream;
      24: aload_3
      25: aload         4
      27: if_acmpne     34
      30: iconst_1
      31: goto          35
      34: iconst_0
      35: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
      38: getstatic     #3 // Field java/lang/System.out:Ljava/io/PrintStream;
      41: aload_3
      42: invokevirtual #5 // Method java/lang/Integer.intValue:()I
      45: aload_1
      46: invokevirtual #5 // Method java/lang/Integer.intValue:()I
      49: aload_2
      50: invokevirtual #5 // Method java/lang/Integer.intValue:()I
      53: iadd
      54: if_icmpne     61
      57: iconst_1
      58: goto          62
      61: iconst_0
      62: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
      65: getstatic     #3 // Field java/lang/System.out:Ljava/io/PrintStream;
      68: aload_3
      69: aload_1
      70: invokevirtual #5 // Method java/lang/Integer.intValue:()I
      73: aload_2
      74: invokevirtual #5 // Method java/lang/Integer.intValue:()I
      77: iadd
      78: invokestatic  #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      81: invokevirtual #6 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z
      84: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
      87: return
复制代码

JDK中代码实现

Character

public static Character valueOf(char c) {
    if (c <= 127) { // must cache
        return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

private static class CharacterCache {
    private CharacterCache(){}

    static final Character cache[] = new Character[127 + 1];

    static {
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Character((char)i);
    }
}
复制代码

Byte

public static Byte valueOf(byte b) {
    final int offset = 128;
    return ByteCache.cache[(int)b + offset];
}

private static class ByteCache {
    private ByteCache(){}

    static final Byte cache[] = new Byte[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Byte((byte)(i - 128));
    }
}
复制代码

Short

public static Short valueOf(short s) {
    final int offset = 128;
    int sAsInt = s;
    if (sAsInt >= -128 && sAsInt <= 127) { // must cache
        return ShortCache.cache[sAsInt + offset];
    }
    return new Short(s);
}

private static class ShortCache {
    private ShortCache(){}

    static final Short cache[] = new Short[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Short((short)(i - 128));
    }
}
复制代码

Integer

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

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}
复制代码

Long

public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

private static class LongCache {
    private LongCache(){}

    static final Long cache[] = new Long[-(-128) + 127 + 1];

    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Long(i - 128);
    }
}
复制代码

Float

public static Float valueOf(float f) {
    return new Float(f);
}
复制代码

Double

public static Double valueOf(double d) {
    return new Double(d);
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享