java中原始数据类型
byte => Byte
short => Short
chart => Character
int => Integer
float => Float
long => Long
double => Double
boolean => Boolean
什么是自动拆箱、装箱
自动装箱就是自动将原始数据类型转换为对应的对象类型(编译器编译时调用valueOf将原始类型转换为对象)
自动拆箱就是自动将对象类型转换为原始数据类型(编译器编译时调用类似于intValue()、doubleValue()方法将对象转换为原始值)
// 自动装箱
Integer i = 1;
// 自动拆箱
int j = i;
自动拆箱、装箱的时机
赋值时
// 自动装箱
Integer i = 1;
// 自动拆箱
int j = i;
方法调用传值时
public void test(Integer i) {
...
}
test(1);
自动拆箱、装箱的弊端
自动拆箱、装箱看似简单方便(用着也确实方便),但是却隐藏着一些弊端
影响性能
在数据量小的时候可能没有太大的影响,但是随着数据量的增多就会额外的创建许多无意义的对象,以及数据转换的过程
Integer sum = 0;
for(int i = 0; i < 100000; i++) {
sum += i;
}
因为sum是Integer对象,不支持 += 操作,所以循环中会进行类似如下的自动的拆箱再装箱的过程:
sum = sum.intValue() + i;
sum = Integer.valueOf(sum);
NullPointerException
Integer a = null;
int b = a;
上面的代码就会抛出空指针异常
== 判断问题(缓存问题)
这个在之前的文章中有介绍《Long == Long 有趣的现象》
重载与自动拆箱、装箱
当重载遇上自动装箱时,情况会比较有些复杂,可能会让人产生有些困惑。在1.5之前,value(int)和value(Integer)是完全不相同的方法,开发者不会因为传入是int还是Integer调用哪个方法困惑,但是由于自动装箱和拆箱的引入,处理重载方法时稍微有点复杂。一个典型的例子就是ArrayList的remove方法,它有remove(index)和remove(Object)两种重载,我们可能会有一点小小的困惑,其实这种困惑是可以验证并解开的,当出现这种情况时,不会发生自动装箱操作。
// demo1
public static void test1(int i) {
System.out.println("int");
}
public static void test1(Integer i) {
System.out.println("integer");
}
test1(1);
test1(Integer.valueOf(1));
输出结果为:
int
integer
// demo2
public static void test1(int i) {
System.out.println("int");
}
//public static void test1(Integer i) {
// System.out.println("integer");
//}
test1(1);
test1(Integer.valueOf(1));
输出结果为:
int
int