0%

3_自动装箱和拆箱

自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象。自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接。

什么是自动装箱和拆箱

装箱: 将 int 类型的变量转为 Integer 类型的变量的过程
拆箱: 将 Integer 类型的变量改为 int 类型的变量的过程

自动装箱和拆箱的几个类型为

byte,short,char,int,long,float,double和boolean

他们分别对应

Byte,Short,Character,Integer,Long,Float,Double,Boolean。

何时发生

赋值时

1
2
Integer iObject = 3; //autobxing - primitive to wrapper conversion
int iPrimitive = iObject; //unboxing - object to primitive conversion

方法调用时

1
2
3
4
5
6
7
8
public static Integer show(Integer iParam){
System.out.println("autoboxing example - method invocation i: " + iParam);
return iParam;
}

//autoboxing and unboxing in method invocation
show(3); //autoboxing
int result = show(3); //unboxing because return type of method is Integer

自动装箱的弊端

无谓的自动装箱和拆箱 浪费性能

由于 Integer 无法直接运算,每次进行算术运算时,都需要将其转化为基本类型,这之间就会多出很多无用的对象,降低运行性能和GC性能。

1
2
3
4
Integer sum = 0;
for(int i=1000; i<5000; i++){
sum+=i;
}

方法重载

list 类有两个方法:remove(int index) 和 remove(Object o)

下面的代码的 list.remove(i); 调用的是 remove(int index) 而非 remove(Object o)

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();

for(int i = -3; i < 3; i++) {
list.add(i);
}
for(int i=0; i<3; i++) {
list.remove(i);
}
System.out.println(set + " " + list);
}
}

对象类型 会出现空指针

1
2
3
4
5
6
private static Integer count;

//NullPointerException on unboxing
if( count <= 0){
System.out.println("Count is not started yet");
}

缓存的数字对象

以 IntegerCache 为例

IntegerCache是在 jdk 1.5 被引入的,其主要目的是节省内存和提高性能:

在第一次加载IntegerCache类时,程序会使用for循环 创建(-128127)范围内的Integer对象,并进行缓存。当创建新的Integer对象时,如果在(-128127)范围内,则直接返回缓存中的对象。

IntegerCache的127高位是可以通过属性java.lang.Integer.IntegerCache.high更改的。