之前在学习java时老师只是说“==”判断的是“地址”,那时候将其当作结论记住了。学习自动装箱和拆箱后才发现背后的秘密:
Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。
先附上一张表,它列出了原生类型和对应的包装类,编译器在使用它们的时候会给我们自动做拆箱和装箱:
Primitive type | Wrapper class |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
int | Integer |
long | Long |
short | Short |
double | Double |
概念:
注意区分基本数据类型和对象!int a = 1与Integer a = 1不等价!
自动装箱:基本类型自动转换为包装类。(例如:int —> Integer)
例如:Integer i = 100;
编译器自动为您作以下的语法编译:Integer i = Integer.valueOf(100);
自动拆箱:包装类自动转化为基本类型。(例如:Integer —> int)
Integer i = 10; //装箱
int t = i; //拆箱,实际上执行了 int t = i.intValue();
注意 :
JVM中有一个缓存区,对于[–128,127]之间的值,创建对象时先看看缓存区中有没有对应的值,如果有:Integer.valueOf(int i) 返回的是缓存的Integer对象(并不是新建对象);如果没有,则将其放到缓存区中,并创建新的对象,用时直接从缓存区中取出。对于范围之外的值,new时则会直接创建新对象。
/*
* Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),
* 它维护了一个Integer数组cache,长度为(128+127+1)=256;
* Integer类中还有一个Static Block(静态块)
*/
例子:
下面的例子和注解详细解释了自动装箱和拆箱相关知识:
一、
/**
* 示范1
* @author HailongYao
*
*/
public class Demo {
public static void main(String[] args) {
int int1 = 10; //数值在栈中存储
Integer int2 = new Integer(10); //对象的属性在堆中存储
Integer int3 = new Integer(10); //重新申请一块内存,创建了新对象
Integer int4 = 10;
Integer int5 = 0;
Integer int6 = 128;
int int7 = 128;
Integer int8 = 128;
System.out.println(int1==int2);//int 跟 Integeter比较,将Integer拆箱再与int比较
System.out.println(int2==int3);//两个对象分别持有不同的地址(引用)
System.out.println(int1==int4);//-128<=10<=127,所以创建int4对象时,将其值放入缓存中,比较时直接从缓存中取出。
//因此比较的是数值,相当于比较两个基本数据类型,结果当然为true
System.out.println(int5==int2-int3);//Java的数学计算是在内存栈里操作的
System.out.println(int6==int7);//int 跟Integer比较时,都是将Integer拆箱
//int6.intValue()转化成基本数据类型,然后在与int比较
System.out.println(int6==int8);//128>127,所以int6和int7分别重新申请了内存
}
}
运行结果:
true
false
true
true
true
false
反编译之后是这样的:
二、
import java.util.ArrayList;
import java.util.List;
/**
* 示范2
* @author HailongYao
*
*/
public class Demo {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList();
numbers.add(-1);
System.out.println(numbers.get(0));
}
}
运行结果:
-1
反编译之后是这样的:
三、
最后上一个归纳总结的整合图,便于大家进一步理解!
总结
通过上述例子,我们理解了自动装箱和拆箱的联系与区别。
下面给出全面支持eclipse4版本的反编译工具Java decompilation的网盘链接,并提供免费下载。
———————————————————————————————
为防止CSDN自动拦截,请在新页面中打开此链接!
网盘链接:https://pan.baidu.com/s/1x45jgjDhIvS9OY2qTsbAfQ
提取码:8hk6
使用方法:解压后运行exe文件,打开并添加.class文件即可反编译。(不用配置eclipse环境)
—————————————————————————————————————————————————————