1.1 基本类型和包装类型
基本类型 | 包装类型 |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
int | Integer |
short | Short |
long | Long |
float | Float |
double | Double |
除了char和int,其他包装类型写法为基本类型的首字母大写。
1.1.1 基本类型和包装类型的区别
- 从内存上:基本类型存在栈里,包装类型为对象存在堆里。
- 从内容上:包装类型是对基本类型的包装,符合POJO规范,基本类型作为自己的成员变量和有set,get方法。
- 从使用上:包装类型可用于泛型,基本类型不可以。
- 从效率上:基本类型更易用,快速。
1.1.2 自动装箱和拆箱
定义:把基本类型转换成包装类型叫装箱(boxing),反之,叫拆箱。 原理:自动装箱通过包装类型的valueOf()方法,拆箱通过包装类型的xxxValue()方法。
1.1.3 自动装箱和拆箱的坑
// 1)基本类型和包装类型
int a = 100;
Integer b = 100;
System.out.println(a == b); # true
// 2)两个包装类型
Integer c = 100;
Integer d = 100;
System.out.println(c == d); # true
// 3)
c = 200;
d = 200;
System.out.println(c == d); # false
上述代码,要知道
==
对基本类型比较值,对引用类型(对象)比较对象地址。
- 当基本类型和包装类型比较时,包装类型自动拆箱成基本类型然后比较。
- 对于-128~127之间的数,Jvm通过优化直接从缓冲池返回此对象。详见后面讲解。
- 对于不在-128~127之间的数,重新创建包装类对象放入堆内存。
1.1.4 包装类对象的缓冲池
上述代码2)就是针对-128~127之间的Integer包装类对象直接从缓冲池内返回。
/**
* 首先会判断i是否在[IntegerCache.low,Integer.high]之间
* 如果是,直接返回Integer.cache中相应的元素
* 否则,调用构造方法,创建一个新的Integer对象
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
总结:
- Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。即对于-128~127之间的值,直接从缓冲池内返回。对于Character范围为0~127。
- Double、Float的valueOf方法的实现是类似的。即直接创建返回新包装类对象。
传包装类型的坑
当将一个Integer的包装类型当作参数传递给函数时,在函数中修改这个Integer并不会影响原来的包装类型。
可以看到包装类型的value是被final修饰的,在函数中修改包装类型的值其实是新建了一个包装类对象。
![]()