JDK源码阅读-------自学笔记(十)(java.lang.Integer包装类初探)
自动装箱和拆箱
- JDK1.5后,Java引入了自动装箱(autoboxing)/拆箱(unboxing)
自动装箱
- 基本数据类型在需要时自动转化为对象
自动装箱
- 对象在需要时自动转化为基本数据类型
注意:
此处的自动是假自动,只是编译器替开发者做了一些事情而已. 也称为编译器蜜糖
实例自动装箱
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 界面书写方式 2 Integer baseDataTyeTranslation = 123; 3 4 // 实际编译器替开发的操作 5 Integer baseDataTyeTranslationFact = Integer.valueOf(123);
可以在生成的.class文件中查看
实例自动拆箱
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 编译器界面书写方式 2 Integer baseDataTyeTranslation = 123; 3 4 // 编译器界面拆箱 5 int autoBoxingInteger = baseDataTyeTranslation; 6 7 // 实际编译器替开发的操作 8 int autoBoxingIntegerFact = baseDataTyeTranslation.intValue();
可以在生成的.class文件中查看
经典错误自动拆箱1------空指针问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 初始化类型 2 Integer baseDataTyeTranslation = null; 3 4 // 赋值给基本数据类型 5 int autoBoxingIntegerFact = baseDataTyeTranslation;
报错:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 Exception in thread "main" java.lang.NullPointerException at com.mr.test.AutoBoxingDemo1.main(AutoBoxingDemo1.java:13) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
因为在拆箱的时候,自动调用intValue()方法,而基本数据类型中没有null这个数值,所以,就会报错
解决方案
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 初始化类型 2 Integer baseDataTyeTranslation = null; 3 4 if (baseDataTyeTranslation != null) { 5 // 赋值给基本数据类型 6 int autoBoxingIntegerFact = baseDataTyeTranslation; 7 }
经典错误自动拆箱2--------缓存问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 初始化类型 2 Integer baseDataTyeTranslation1 = Integer.valueOf(-128); 3 4 Integer baseDataTyeTranslation2 = Integer.valueOf(-128); 5 6 System.out.println(baseDataTyeTranslation1 == baseDataTyeTranslation2);
返回结果是true,'=='比较的是对象的索引,而此处结果却是true,在[-128,127]区间的数,在创建对象的时候,是走缓存的,缓存时,先检测范围,如果是缓存范围内,就调用缓存对象,不是范围内,就新建对象。
源码:
1、-128-127走缓存
2、缓存中数据
3、在范围内,加入缓存中
改写方式:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class AutoBoxingDemo1{ 2 3 public static void main(String[] args) { 4 5 6 // 初始化类型 7 Integer baseDataTyeTranslation1 = AutoBoxingDemo1.valueOf(-128); 8 9 Integer baseDataTyeTranslation2 = AutoBoxingDemo1.valueOf(-128); 10 11 System.out.println(baseDataTyeTranslation1 == baseDataTyeTranslation2); 12 13 14 } 15 16 17 public static Integer valueOf(int i) { 18 return new Integer(i); 19 } 20 }
十年磨一剑,一剑破万法