自动装箱和拆箱
自动装箱和拆箱
目的:日常开发中,靠这些基本数据类型
几乎能够满足我们的需求,但是基本类型终究不是对象。将原始类型值自动地转成对应的对象。自动装箱与拆箱的机制可以让Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接。
自动装箱:
Java自动将原始类型值转换成对应的对象,比如讲int的变量转换成Integer对象,这个过程叫做装箱
int i = 100;
Integer a = i;
拆箱
将包装类转成基本数据类型,比如将Integer对象转换成Int类型
Integer a;
int i = a;
1. 为什么要有包装类(或封装类)
为了使基本数据类型的变量具有类的特征,引入包装类。具有类的特征之后,就可以调用方法
2. 基本数据类型与对应的包装类:
3. 类型间的转换
4. 何时发生自动装箱和拆箱
赋值、数值运算时
Integer I = 3;//3是基本数据类型Int型的,直接装箱成Integer类型
int i = I;//I是Integer类型,直接拆箱变为了int类型
方法调用时:
public static Intefer show(Integer i){
System.out.println("autoboxing example")
}
自动装箱、拆箱中的坑
public void testAutoBox2() {
//1
int a = 100;
Integer b = 100;
System.out.println(a == b);
//2
Integer c = 100;
Integer d = 100;
System.out.println(c == d);
//3
c = 300;
d = 300;
System.out.println(c == d);
}
true true false
以上是输出的结果,第一个和第二个倒是还可以理解,但是第三的话,有需要看看源码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); }
可以看到,这里面不是简单的
new Integer()
,而是用IntegerCache,IntegerCache是可以设置范围的,默认是-128~127private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { 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++); int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); ....
我们上面当赋值100给Integer时,刚好在这个range内,所以从cache中取对应的Integer并返回,所以二次返回的是同一个对象,所以比较是相等的,当赋值300给Integer时,不在cache 的范围内,所以会new Integer并返回,当然比较的结果是不相等的。