1. 装包和拆包
java提供的基本类型以及其对于的包装类型
基本类型 | 对于包装类型 |
---|---|
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
void | Void |
下面以Integer为例子介绍装箱和拆箱:
装箱存在的情况:
int 赋值给Integer 即基本类型赋值给包装类型时
等价于 Integer i = Integer.valueOf(1); java自动完成装箱操作
Integer i = 1;
拆箱存在的情况:
int与Integer比较 及基本类型和包装类型比较时
i对象会自动拆箱int类型和j进行比较
new Integer(1) == 1// 等价于 i.intValue() == j
2. Integer原理及缓存机制
Integer是int基本数据类型的包装类,无非是在int基本类型的基础上增加了一些操作和其他属性。
Integer的实际对应int值是通过intValue()方法获取的,源码如下:
public final class Integer extends Number implements Comparable<Integer> {
@Native public static final int MIN_VALUE = 0x80000000;
@Native public static final int MAX_VALUE = 0x7fffffff;
// 对应int基本类型的数值 是一个常量整型
private final int value;
public int intValue() {
return value;
}
...省略
}
前面说过的装箱用到的一个方法是valueOf(),让我们看看源码:
可以看到传入的i 先和IntegerCache比较 在IntegerCache中则返回IntegerCache中的Integer不存在则new一个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实现如下:
IntegerCache是个Integer的内部类,在类加载的时候static代码块创建了256个缓存Integer对象,范围-128至127
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.
}
}
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)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
知道Integer缓存的存在,下面我们看看下面的几个例子:
注:== 对象比较比较的是对象的引用是否相等 equals则根据对象内部的实现情况进行比较
Integer i = 1; //i = Integer.valueOf(1) 取缓存对象 IntegerCache.cache[129]
Integer j = 1; //j = Integer.valueOf(1) 取缓存对象 IntegerCache.cache[129]
System.out.println(i == j);//输出true i 和j指向同一个对象
Integer i = 1; //i = Integer.valueOf(1) 取缓存对象 IntegerCache.cache[129]
Integer j = new Integer(1); // 新创建一个对象
System.out.println(i == j);//输出false i 和j指向的不是同一个对象
Integer i = 128; //i = Integer.valueOf(128) 不在缓存访问内 new Integer(128)
Integer j = 128; //j = Integer.valueOf(128) 不在缓存访问内 new Integer(128)
System.out.println(i == j); //输出false i 和j指向的不是同一个对象
所以Integer对象在比较是否相等的时候 不要用 == 用equals Integer内部实现了自己用equals,源码如下:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}