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