装箱和拆箱
//自动装箱
Integer a = 100;
//自动拆箱
int b = a;
简而言之:
自动装箱:基本数据类型转换成引用数据类型
自定拆箱:引用数据类型转换成基本数据类型
需要装箱拆箱的数据类型
当执行 Integer a = 100;根据反编译查看,执行这段代码,系统帮我们执行了 Integer a = Integer.valueOf(100);
执行int b = a; 系统帮我们执行了 int b = a.intValue();
根据查看Integer的valueOf()的源码
//This method will always cache values in the range -128 to 127,
//inclusive, and may cache other values outside of this range.
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
也就是在[-128 - 127]范围内的值,会直接从缓存中拿,不会创建新的对象,但是不在这个范围内的值,就会创建新的对象
从源码中可以看出来 Integer的缓存最低值一定是-128 是不可以修改的,但是上限值high 是可以修改的。
通过jvm参数: -Djava.lang.Integer.IntegerCache.high=1024 修改为1024
同理根据源码查看:
基本类型
|
包装类型
|
缓存范围
|
附加
|
byte
|
Byte
|
-128 - 127
|
|
short
|
Short
|
-128 - 127
|
|
int
|
Integer
|
-128 - 127
|
最大值可以修改
|
long
|
Long
|
-128 - 127
|
|
char
|
Character
|
0-127
|
|
boolean
|
Boolean
|
true/false
|
所有的true和false都是同一个对象
|
float
|
Float
|
只要执行valueOf()都会创建新的对象
|
没有缓存
|
double
|
Double
|
只要执行valueOf()都会创建新的对象
|
没有缓存
|
int a = 110;
int b = 110;
Integer c = 110;
Integer d = 230;
Integer e = 230;
Integer f = 110;
Integer g = 110;
Integer h = 0;
Integer i = new Integer(230);
Integer j = new Integer(230);
Integer k = new Integer(110);
Integer l = new Integer(110);
Integer m = new Integer(0);
System.out.println(a == b);//t
System.out.println(a == c);//t
System.out.println(d == e);//f
System.out.println(f == g);//t
System.out.println(f == g + h);//t
System.out.println(i == j);//f
System.out.println(k == l);//f
System.out.println(k == l + m);//t
System.out.println(l == b);//t
解释:
- 当==两边是基本数据类型,比较的是值。
- 当==两边是引用数据类型时,比较的是地址。
- 当==两边有一个基本数据类型有一个是基本数据类型时,先把引用数据类型拆箱,再和基本数据类型比较值
- 当==两边有表达式时,先计算表达式,因为==的优先级最低。再把引用数据类型拆箱再比较值
但是频繁的装箱会创建对象,消耗内存,所以我们应该尽量避免