一.概述 java允许把基本类型与其对应的包装器类型之间自动相互转换。 - 自动装箱:Integer i=(int)100,把int 类型的直接赋值给Integer类型;
- 自动拆箱:int a=new Integer(100),把Integer类型直接赋值给int类型
二.原理自动拆装箱是由编译器完成的!我们写的代码,再由编译器“二次加工”,然后再编译成.class文件! - int a = new Integer(100); 编译器加工为:int a = new Integer(100).intValue();
- Integer b = a;编译加工后为: Integer b = Integer.valueOf(a);
三.误区- int[] intArr = {1,2,3};
- Integer[] integerArr = intArr;
复制代码 编译是无法通过,而且运行的时候会报这么一个错误
那么为什么编译的时候无法通过呢? 原因是int[]是引用类型,而不是基本类型。而自动拆装箱只是在基本类型与其对应的包装器类型之间进行转换!也就是说,int[]和Integer[]是两种不同的引用类型。 四.一个小的题目题目:- Integer i1 = 100;
- Integer i2 = 100;
- Integer i3 = 200;
- Integer i4 = 200;
-
- System.out.println(i1 == i2);
- System.out.println(i3 == i4);
复制代码
如果这道题给你做,你的答案会是什么?是两个true,还是两个false呢.两个true或者两个两个false都是错的.答案是true 和false.这个疑团要从编译器加工后的代码开始,我们先来看编译器加工过后的代码:- Integer i1 = Integer.valueOf(100);
- Integer i2 = Integer.valueOf(100);
- Integer i3 = Integer.valueOf(200);
- Integer i4 = Integer.valueOf(200);
-
- System.out.println(i1 == i2);
- System.out.println(i3 == i4);
复制代码
除了看编译器加工后的代码,我们再看看Integer的一个方法:- public static Integer valueOf(int i) {
- final int offset = 128;
- if (i >= -128 && i <= 127) { // must cache
- return IntegerCache.cache[i + offset];
- }
- return new Integer(i);
- }
复制代码
结合以上两个片段你应该可以看到,疑团在Integer.valueOf()方法身上。传递给这个方法100时,它返回的Integer对象是同一个对象,而传递给这个方法200时,返回的却是不同的对象。这是我们需要打开Integer的源码(这里就不粘贴Integer的源代码了),查看它的valueOf()方法内容。
Integer类的内部缓存了-128~127之间的256个Integer对象,如果valueOf()方法需要把这个范围之内的整数转换成Integer对象时,valueOf()方法不会去new对象,而是从缓存中直接获取,这就会导致valueOf(100)两次,都是从缓存中获取的同一个Integer对象!如果valueOf()方法收到的参数不在缓存范围之内,那么valueOf()方法会new一个新对象!这就是为什么Integer.valueOf(200)两次返回的对象不同的原因了。其中Integer的取值范围是在学习VB的时候学习的.
|