Java学习:封装类和自动装、拆箱
集合中只能存在对象,而不能存在基础数据类型,于是封装类出现了
- 封装类
就是对基本数据类型进行封装,并用它生成对象,以便以对象方式操作基本数据类型。
每一个基本数据类型都对应一种封装类:
基本数据类型 | 封装类 | 继承关系 |
---|---|---|
byte | Byte | Number—>Object |
short | Short | Number—>Object |
int | Integer | Number—>Object |
long | Long | Number—>Object |
float | Float | Number—>Object |
double | Double | Number—>Object |
boolean | Boolean | Object |
char | Character | Object |
- (自动)装、拆箱
将基本数据类型(自动)转为对应的封装类,便是(自动)装箱;将封装类(自动)转为对应的基本数据类型就是(自动)拆箱
// 装箱
Integer i1 = new Integer(1);
// 可看作 int i1 = 1; Integer i2 = new Integer(i1);
// 装箱就通过构造方法,将基本数据类型构造成它所对应的包装类的对象
// 通过研究Integer类的成员方法 我们可以知道上述写法过于麻烦
// 在java中,SUN公司提供一套机制可以简化为下述代码
// 自动装箱
Integer i1 = 1;
// 同样我们可以从Integer类中了解到一个叫value的方法
// 拆箱
int i2 = i1.intvalue();
// 同样可简化为下述代码
// 自动拆箱
int i2 = i1;
自动装拆箱的意义:方便编程
- 一些需要注意的问题
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1 == i2);// true "==" 号只是判断当前引用代表的内存空间存放的地址值。
System.out.println(i3 == i4);// false
为什么会造成这种差异呢?
通过分析valueOf方法可以知道,当值在-128到127之间时,返回 IntegerCache.cache[i + (-IntegerCache.low)] ; 其它则返回 new Integer(i) 。
// IntegerCache.cache[i + (-IntegerCache.low)]是什么? 看源码
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property 高值可以通过属性来配置
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, 127);
// Maximum array size is Integer.MAX_VALUE 最大数组大小
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
// 如果该属性无法解析为 int,则忽略它
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
// 必须属于 [-128, 127] 这个范围
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
从上述可看出IntegerCache类中提前就初始化了一个Interger数组,范围为-128到-127。故 i1 与 i2 返回 cache[] 数组中的对象,属于同一个对象,从而返回true;而 i3 和 i4 返回 new Integer() ,并不属于同一对象,结果为false
其他封装是否一样呢?
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1 == i2);// false
System.out.println(i3 == i4);// false
这又是怎么回事?
原因还得从源码找
public static Double valueOf(double d) {
return new Double(d);
}
可以看出 Double 封装类的 valueOf() 是返回一个新的封装类对象,故 i1 == i2 与 i3 == i4 结果一样
- 小结
- Inerger 派别: Integer、Short、Byte、Character、Long这几个类的valueOf()方法的实现是类似的,根据数据大小返回对象,可能相同可能不同
- Double 派别:Double、Float的valueOf()方法的实现是类似的,都返回不同的对象