关于拆包装包这块,以前一直是一知半解,也觉得没有什么需要特别写出来的必要,反正是 JAVA 自带的性质。
最近发现里面还是有一些以前不曾在意的机制的,简单说一下。
1 | public static void main(String[] args) { |
- 因为自动装包机制,a 和 b 实际指向的是对象的内存地址。而两个 new 出来的对象地址一定不相等
- 因为自动拆包机制,当包装类型与基础类型比较时,会进行拆包,对基础类型的值进行比较,所以相等
- 当包装类型进行计算时,会进行自动拆包,故比较的是值,而不是地址,为true。
- 因为基础类型的缓存机制,int类型会缓存[-128,127]的值,int a = 1,实际上是类似于调用了 int a = Integet.valueOf(1),如果缓存中存在,则会直接返回该对象,并不会new,所以同一个对象的内存引用地址一样,故相等
- 同上,只是128超出了缓存的范围,因此是new出来的,所以两个对象引用地址不同。
- 声明时是 int, int a2 = new Integer(1236) 实际上是 int a2 = new Integer(1236).intValue(); 且当包装类型与基础类型比较时,会自动拆表比较值。
根据自身理解,自动拆包有一下几种情况:
- 当存在算术符号时
- 当包装类型与基础类型比较时
- 声明对象时使用基础类型声明时
自动包装有以下几种情况:
- 声明对象为包装类型时,包括new,和直接给定值。区别在于,new的时候一定是一个新的对象,而后者通常调用了XXX.valueOf(a),有可能会从缓存中直接获取。
- int a = new Integer(1);
- int a = 1;
更详细的文档请看: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
Tips:
包装类型缓存范围如下:
类型 | 范围 |
---|---|
Byte,Short,Integer,Long | [-128,127] |
Character | [0,127] 前128个字符 |
Boolean | true,false |
Float, Double | 无缓存 |