本节介绍JAVA中的自动装箱和自动拆箱
自动装箱和自动拆箱就是将原始类型自动转换成包装类,包装类自动转换成原始类型。
比如int与Integer,double和Double之间会自动进行转换。
其中int->Integer是装箱,Integer->int是拆箱,自动装箱和自动拆箱就是这么一个过程。
我们日常写代码使用这个拆箱装箱特性比较多的一般就是泛型。比如集合的使用。
public static void main(String[] args) throws NotSuchStudentFoundException {
List<Integer> list = new ArrayList<>();
list.add(1);//实现了int 1到Integer的自动装箱
int i = list.get(0);//实现了Integer到int的自动拆箱
}
–>自动拆箱和装箱就是一个自动转换原始类型和包装类型的过程
int,double,float,boolean,char,short,byte,long
Integer,Double,Float,Boolean,Character,Short,Byte,Long
八大原始数据类型对应的包装类。
那么这些东西都是自动做的。我们有必要去了解吗?
–>答:有的,懂了自动装箱和自动拆箱内部的过程。你就能写出比较高效的代码。这样的代码在日常开发中其实很多人都不会的。因为没有这个意识。
自动拆箱和装箱的过程
(1)首先看看有无自动拆箱的区别
//在没有自动拆箱装箱前
public static void main(String[] args) throws NotSuchStudentFoundException {
Integer autoBox = Integer.valueOf(5);//装箱,将int 5转换成Integer 5
int unBox = autoBox.intValue();//拆箱,将Integer 5转换成int 5
}
//有了自动拆箱和装箱后,编译器会帮我们自动调用valueOf()和intVlue()来装箱和拆箱
public static void main(String[] args) throws NotSuchStudentFoundException {
Integer autoBox = 5;//自动装箱,将int 5转换成Integer 5
int unBox = autoBox;//自动拆箱,将Integer 5转换成int5
}
(2)接着看看装箱过程中的valueOf()这个方法发生了什么?
简单来说就是创建了一个新的Integer对象
在看看intValue()
过程就是写一个Integer i = 5;在内部使用了valueOf(5)方法创建了一个新的对象new Integer(5)同时把这个int 5给保存给value。然后使用intValue()方法把这个保存下来的value直接返回回去。
–>结论,使用Integer时会隐式的创建一个新对象Integer.
这些过程都是自动执行,这样原始类型int和包装类Integer就自动转换完成了
自动装箱和拆箱的注意事项
1,保存在本地的数据尽量使用原始类型。
什么叫保存在本地?通俗一点就是这个数据是在我这个JAVA上创建的,不是从别的机器或软件获取的
Integer num = 0;
for(int i = 1;i<1000;i++){
num = num +i;
}
比如这么一段代码。由于+不适用于Integer.所以每一个循环内部都是这样的
num = num.intValue()+i;
num = new Integer(num);
也就是说每次循环都会创建一个对象.循环了1000次就创建了1000个对象。这些对象都是无用的。如果改成int num = 0; 就可以省去创建1000个对象的资源。
–>这个Integer num = 0;就是从我这个JAVA文件创建的。
使用时要考虑到装箱会创建对象。所以要合理的判断是使用包装类还是原始类
2,使用包装类比较时用equals()比较而不是"=="
Integer num1 = 222;
Integer num2 = 222;
System.out.println(num1==num2);
结果输出:false
原因就是num1和num2在包装的过程中都创建了对象.而这两个并不是同一个对象所以是false.
但是如果值是-128-127这个会输出true,因为JVM会缓存-128-127的Integer对象。这时候就不会创建新的Integer对象直接从缓存拿。所以结果是同一个对象因此是true
Integer num1 = 111;
Integer num2 = 111;
System.out.println(num1==num2);
结果输出:true
3,包装类可以为null,所以使用时可能抛出空指针异常
public static void main(String[] args) throws NotSuchStudentFoundException {
School school = new School();
if (school.getNum()>0) { }//出异常了
}
public class School {
private Integer num;
public Integer getNum() {
return num;
}
}
结果:
所以使用时要注意对Integer为null的处理防止程序出异常导致中止。
什么时候用包装类?
当你允许这个值为null或者这个值可能为null时就使用包装类,否则的话就选择使用原始类。
总结:
1,自动装箱和自动拆箱是什么?
原始类型和包装类型的自动转换,途中编译器自动调用valueOf()来进行装箱,使用xxxValue()来进行拆箱。装箱过程会生成一个新的对象
2,注意事项.
(1)要注意装箱过程中会生成新对象。所以使用包装类时要考虑避免生成无用的对象。
(2)包装类对比使用equals对比而不是"=="
(3)包装类可以为Null,所以使用时如果没有初始化要对包装类为null的情况进行处理,否则可能抛出空指针异常导致程序中断。