Java中的自动拆箱装箱(Autoboxing&Unboxing)
一、基本类型打包器
1、基本类型:long、int、double、float、boolean
2、类类型:Long、Integer、Double、Float、Boolean
区别:基本类型效率更高,类类型的对象却可以携带更多的信息。
public class TestInteger01 { public static void main(String[] args) { int a = 10; int b = 20; Integer A = new Integer(a); Integer B = new Integer(b); System.out.println(a / 3); System.out.println(A.doubleValue()/ 3); System.out.println(A.compareTo(B)); } } /* 输出结果: 3 3.3333333333333335 -1 */
doubleValue()可以将打包值以double类型返回
compareTo()可以与另一个Integer对象比较,相同为0,小于为-1,大于为1
二、自动拆箱和装箱
Integer A = 10; //自动装箱 int a = A; //自动拆箱
自动拆箱和装箱的内幕
看第一个例子,这个例子声明了int和Integer两个类型,“==”为比较是否参考于同一个对象
public class TestInteger02 { public static void main(String[] args) { int a = 100; int b = 100; if (a == b){ System.out.println("int基本类型:a == b"); } else{ System.out.println("int基本类型:a != b"); } Integer c = 100; Integer d = 100; if (c == d){ System.out.println("Integer类类型:c == d"); } else{ System.out.println("Integer类类型:c != d"); } } } /* 输出结果: int基本类型:a == b Integer类类型:c == d */
由结果可知,a和b,c和d都是同一个对象。
再来看第二个例子,我们将abcd的值全部改为200,输出却出现了意想不到的结果。
public class TestInteger03 { public static void main(String[] args) { int a = 200; int b = 200; if (a == b){ System.out.println("int基本类型:a == b"); } else{ System.out.println("int基本类型:a != b"); } Integer c = 200; Integer d = 200; if (c == d){ System.out.println("Integer类类型:c == d"); } else{ System.out.println("Integer类类型:c != d"); } } } /* 输出结果: int基本类型:a == b Integer类类型:c != d */
我们发现,此时a和b还是同一个对象,c和d却已经不是同一个对象了!
这是什么原因呢?我们可以查看java/lang/Integer.java
public static Integer valueOf(int i) { return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128]; }
这段代码的意思是,在Integer类中,当传进来的值在(-128—127)之间时,便会查看缓存中有没有打包过相同的值,如果有就直接返回,如果没有就new创建。
当传进来的值不在(-128—127)这个区间时,就直接new创建。所以c和d为200,已经超出区间,所以各自开辟一块内存空间存储数据,所以也不会引用自同一个对象。
而基本类型int,就不会有这个烦恼,每次传值,都会查看缓存中是否已经存在。
理解了这个,我们也就理解了基本类型与String型的区别。
我在这篇随笔中(Java中关键字super与this的区别),初步介绍了基本类型与String型的用法区别,但并没有深入认识到这点,而今天看到了林信良先生的java学习笔记,终于有一种醍醐灌顶的感觉。