1. Java包装类
Java中基本数据类型和其对应的包装了类如下:
基本数据类型 | 包装了类 |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
其中前六行对应于整数数据,后两行对应于浮点数数据。而Java中所有数据都是有符号的数据,因此
byte:1字节,char:2字节,short:2字节,int:4字节,long:8字节,float:4字节,double:8字节。
2.自动拆箱、自动装箱
Java的自动拆箱装箱对应于其中的xxxValue()和valueOf()方法。本身包装类是不能进行基本数据类型的运算的,所以有包装类进行的运算会自动拆箱为基本类型进行运算,而基本数据类型赋值给包装类则会自动装箱。例:
Integer a = 1+2;//自动装箱
int b = new Integer(1);//自动拆箱
int c = 1 + (new Integer(2));//自动拆箱
3. 与包装类相关的==以及equals()运算
equals()方法仅包装类可以使用,在之前《java == equals hashCode区别》中已经讲过这几种运算的关系。对于未重写equals方法的基本数据类型的包装类来说,equals方法比较的是两个变量是不是同一个对象的引用,这与==运算发挥着同样的作用。
包装类有两种方式创建对象:
Integer a = 123;//直接赋值 等价于 Integer a = Integer.valueOf(123);
Integer a = new Integer(123);//创建一个新的对象
这些值的比较遵循下面规律:
- 首先基本类型与包装类进行比较,或者包装类进行了运算,那么结果可以理解为基本类型之间的值比较,因为它会自动拆箱。
- 对于有缓存的包装类,在缓存范围之内:两个直接赋值(或valueOf)的对象比较,一定是同一个对象;而在缓存之外比较,则不是同一个对象。
- 对于两个new来的对象,或者一个赋值和一个new的对象,二者永远不等。
下面是以Integer类为例做的演示:
//参与运算的比较
int a = 1;
Integer b = 1;
Integer zero = 0;
Integer c = new Integer(1);
Integer d = new Integer(1);
a==b; a==c; a == b+zero; c == c + zero;1 == c + 0;//true
c ==d;//false
Integer e = 128;
Integer f = 128;
e == f;//false 因为超出缓存
六个有缓存的包装类的缓存范围:
包装类 | 缓存范围 |
---|---|
Boolean | true,false |
Byte | -128 ~127 |
Character | -128~127 |
Short | -128~127 |
Integer | -128~127 |
Long | -128~127 |
这里以Integer类中的缓存代码为示例:
public static Integer valueOf(int i){
if( i >= IntegerCache.low && i<= IntegerCache.high)
return IntegerCache.cache[i + (- IntegerCache.low)];
return new Integer(i);
}
其中IntegerCache
是Integer中的一个静态缓存类
public static class IntegerCache{
static final int low = -128;
static final int high;
static final Integer cache[];
static{
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if(integerCacheHighPropValue != null){
try{
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i,h);
h = Math.min(i,Integer.MAX_VALUE-(-low)-1);
}cache(NumberFormatException nfe){
}
}
high = h;
cache = new Integer[(high-low)+1];
int j = low;
for(int k = 0;k<cache.length;k++)
cache[k] = new Integer(j++);
assert IntegerCache.high >=127 ;//验证确保high大于等于127;
}
}