Java 自动装箱、拆箱机制及部分源码分析

Integer i = 10;  //装箱,反编译后发现调用Integer.valueOf(int i)
int t = i;   //拆箱,反编译后发现调用i.intValue()
public class Solution {
	public static void main(String args[]) {
		Integer i1 = 1,i2 = 1,i3 = 200,i4 = 200;
		System.out.println(i1 == i2);
		System.out.println(i3 == i4);
	}
}

输出结果:

true

false

原因在于Integer.valueOf(int i)为了优化运行的效率,减少对象的new操作,做了一个IntegerCache缓存,-128-127之间的Integer对象直接映射到缓冲中。

源码如下:

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

private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

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

    private IntegerCache() {}
}

同样类型的还有Short、Byte、Character、Long;

Double和Float由于本身自带偏差,所以不带有Cache。

对于Boolean类型的变量,直接采用类似于单例模式的方法进行valueOf(boolean b)方法

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

 因此

public class Solution {
    public static void main(String args[]) {
        Boolean b1 = true, b2 = true;
        System.out.println(b1 == b2);
        b2 = false;
        System.out.println(b1 + " " + b2);
    }
}

输出

true

true false(类似String,是引用操作,不是赋值操作)

原文地址:https://www.cnblogs.com/tonyluis/p/5796129.html