Integer类拆箱装箱及比较

1.JAVA装箱与拆箱

  • 装箱:就是自动将基本数据类型转换为包装器类型
  • 拆箱:就是自动将包装器类型转换为基本数据类型

2.JAVA基本类型对应的包装器类

基本数据类型 包装器类型
boolean Boolean(未定义)
byte Byte(1字节)
short Short(2字节)
char Character(2字节)
int Integer(4字节)
float Float(4字节)
long Long(8字节)
double Double(8字节)

注:各类型所占字节数,可以使用BYTES属性查看。例如:
System.out.println(Integer.BYTES);//4

3.Integer的装箱

  • 例如:Integer x = 1;实际执行的是Integer x = Integer.valueOf(1);的装箱操作。
  • Integer类下的valueOf方法源码如下:
public static Integer valueOf(int i) {
    
    
	if (i >= IntegerCache.low && i <= IntegerCache.high)
		return IntegerCache.cache[i + (-IntegerCache.low)];
	return new Integer(i);
}

其中IntegerCache.low为-128,IntegerCache.high为127,当在这个范围内时返回的IntegerCache内类中cache数组里边的值,否则重新创建Integer对象。
IntegerCache类如下:

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() {
    
    }
}

可以看出IntegerCache提前将数值为-128到127的Integer对象创建好,存放在cache数组内,当使用这一区间的数值时,直接返回cache数组中的数据(数据为Integer对象)。

4.Integer拆箱

  • 创建Integer对象是将int数值放在了private final int value;的全局属性中。
  • 源码如下:
public Integer(int value) {
    
    
	this.value = value;
}
  • Integer拆箱示例如下:
Integer x = new Integer(1);
int y = x;//实际执行的为:int y = x.intValue()
  • Integer类下intValue()源码如下:
public int intValue() {
    
    
	return value;
}

拆箱就是返回Integer对象中存放的int值。

5.Integer中的equals和==

  • equals比较的对象里的值是否相等,==是比较的是对象在内存中地址是否相等。
//1.情景一
Integer a1 = 127;
Integer b1 = 127;
System.out.println(a1==b1);//true
System.out.println(a1.equals(b1));//true

//2.情景二
Integer a2 = 128;
Integer b2 = 128;
System.out.println(a2==b2);//false
System.out.println(a2.equals(b2));//true

//3.情景三
Integer a3 = new Integer(127);
Integer b3 = new Integer(127);
System.out.println(a3==b3);//false
System.out.println(a3.equals(b3));//true

//4.情景四
Integer a4 = new Integer(128);
int b4 = 128;
System.out.println(a4==b4);//true
System.out.println(a4.equals(b4));//true	

(1) Integer中==比较

  • 情景一:因为Integer a1 = 127;Integer b1 = 127;执行的是装箱操作调用Integer.valueOf(127);因为a1和b1值在-128到127之间,代码调用IntegerCache类下的cache数组,每次返回的都是同一个对象,对象地址相同所以a1==b1 为true;
  • 情景二:因为Integer a2 = 128;Integer b2 = 128;不在-128到127之间,所以每次都创建新的Integer对象,对象不同,内存地址不同,所以a2==b2为false;
  • 情景三:每次都创建新的Integer对象,对象不同,内存地址不同,所以a2==b2为false;
  • 情景四:Integer a4 = new Integer(128);int b4 = 128;当执行a4==b4时a4其实执行了Integer下的intValue()的操作,所以a4==b4实际比较的是int值,所以a4==b4为true

(2) Integer中equals的比较

  • Integer中equals源码如下:
public boolean equals(Object obj) {
    
    
	if (obj instanceof Integer) {
    
    
    	return value == ((Integer)obj).intValue();
    }
    return false;
}

通过上面源码可知实际上是int值的比较所以数值相等时就会返回true。
注:情景四:b4其实执行了一次装箱操作,一次拆箱操作

6.总结

  • 没啥总结的,写的很乱,慢慢看吧。如果好的建议,记得留言。

猜你喜欢

转载自blog.csdn.net/u012722296/article/details/104048543