我所知道的装箱拆箱
装箱
大家都听说过装箱拆箱,但是装箱是个怎么样的过程?
废话不多说直接上代码:
然后我们跟随debug去瞧瞧怎么回事,当程序执行到sum=i,奇怪的事情发生了
我们发现i=125,并且进入到Integer类的valueOf方法,然后去验证这个数字是否>=IntegerCache.low && <=IntegerCache.high,如果验证通过就返回 IntegerCache.cache[下标]。
这三个是什么东东?我们点进去看看。
我们可以看到Integer里面有个静态内部类 IntegerCache, 并且定义了三个常量。
low=-128 ,high=?, cache[]=? 往下拉拉看
我们可以看见high=127,并且把-128 - 127存进cache数组中,这样我们每次int为 -128—127 的时候都是从cache中取得。但是超过这个范围,就会变成 new Integer(int)。
同时这也是为什么区间(-128 -—127) a == b为true。
如:Integer a=127,b=127; a==b 等于true,大家都是一个地方,肯定true了。
但是new Integer() 就是false,你说你都搬家了,大家已经形同陌路了,肯定false了
那么拆箱呢?
拆箱
Debug同样的地方我们互换类型。
我们发现当Integer转化int时会隐式调用intValue() 这一过程又叫拆箱。
为何有时应当避免装箱拆箱
我们在看一组代码(以下代码来自(Effective java)
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
Long sum=0L;
for (int i = 0; i <Integer.MAX_VALUE ; i++) {
sum+=i;
}
System.out.println(sum);
long endTime= System.currentTimeMillis();
System.out.println(endTime-startTime);
}
消耗时间:6162
当sum类型为long时,我们在看下执行了多长时间
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long sum=0L;
for (int i = 0; i <Integer.MAX_VALUE ; i++) {
sum+=i;
}
System.out.println(sum);
long endTime= System.currentTimeMillis();
System.out.println(endTime-startTime);
}
消耗时间:601
我们可以看到整个程序执行效率相差10倍!!所以我们有时候应该避免拆箱装箱
拆箱装箱这么麻烦,还要包装类干嘛?
难道是因为JAVA面向对象编程吗!!
List arr= new ArrayList<int>();
上面这种写法直接报错,编译期都过不去,因为java规定集合<泛型>只能是Object及其子类
问:我定义个int类型 为什么能够添加进list呢?int是基本类型啊
List arr = new ArrayList();
int a=1;
arr.add(a);
我们再arr.add(a)位置debug
会发现实际我们在集合中添加基本类型的时候也会隐式装箱
那么包装类不是够用了吗,还要基本类型干嘛?
我们知道对象是存在堆中的,基本类型是放在栈中的(局部变量),栈的速度优于堆,我们总不能每次一个局部变量都要在堆中创建一块内存吧,并且方法执行完之后栈中的局部变量空间会被立即释放,而堆中却不是。而且速度还没栈快,为什么不选择在栈中呢?