Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类。以下是基本数据类型对应的包装类:
基本数据类型 | 包装类 |
byte(1字节) | Byte |
short(2字节) | Short |
int(4字节) | Integer |
long(8字节) | Long |
float(4字节) | Float |
double(8字节) | Double |
char(2字节) | Character |
boolean(1/8字节) | Boolean |
自动装箱、拆箱:
在 jdk1.5 以前,创建 Integer 对象需要调用其构造方法:
Integer i = new Integer(5);
jdk1.5 具有自动装箱拆箱功能:
Integer i = 5; //装箱
int j = i; //拆箱
其原理是调用了 Integer 的 valueOf(int) 和 Integer 对象的 intValue() 方法:
public static void intTest() {
Integer integer = 2;
int i = integer;
System.out.println(i);
}
//反编译后
public static void intTest() {
Integer integer = Integer.valueOf(2);
int i = integer.intValue();
System.out.println(i);
}
IntegerCache 类:
IntegerCache 是 Integer 类中一个私有的静态类,用于整型对象的缓存。
Integer i1 = 2;
Integer i2 = 2; System.out.println(i1 == i2); //true
该缓存策略仅在自动装箱时适用,也就是使用 new Integer() 的方式构建的 Integer 对象!=:
Integer i1 = new Integer(2);
Integer i2 = new Integer(2); System.out.println(i1 == i2); //false
并且只适用于整数区间 -128 到 +127:
Integer i1 = 300;
Integer i2 = 300; System.out.println(i1 == i2); //false
源码里 Integer 的 valueOf(int) 方法:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
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() {}
}
源码里规定了缓存的范围最小为:-128 到 +127 ,最大值映射到 java.lang.Integer.IntegerCache.high,可以使用 JVM 的启动参数 -XX:AutoBoxCacheMax=size
设置最大值。
其他包装类:
Byte,Short,Long,Character 也有相应的缓存类;
Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127;
另外,只有 Integer 可以通过参数改变范围。
boolean:
Boolean b1 = false;
Boolean b2 = false;
Boolean b3 = true;
Boolean b4 = true; System.out.println(b1==b2); //true
System.out.println(b3==b4); //true
Integer 与 Long:
Integer a = 1;
Integer b = 2;
Long g = 3L;
Long h = 2L; System.out.println(g==(a+b)); //true
System.out.println(g.equals(a+b)); //false
System.out.println(g.equals(a+h)); //ture
"==" 与 equals :
1,”==“可以用于原始值进行比较,也可以用于对象进行比较,当用于对象与对象之间比较时,比较的不是对象代表的值,而是检查两个对象是否是同一对象,这个比较过程中没有自动装箱发生。
2,进行对象值比较不应该使用”==“,而应该使用对象对应的 equals 方法。
3,equals 方法是 Object 类的一个方法:
public boolean equals(Object obj) {
return (this == obj);
}
许多类会重写这个方法:
① Integer 类重载了该方法:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Integer i1 = 300;
Integer i2 = 300; System.out.println(i1 == i2); //false 两个不同的地址引用
System.out.println(i1.equals(i2)); //true 两个相同的值(变为两个 int 之间的比较,所以比较值)
② String 重载了该方法:当两值不 == 时,比较他们的值
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
所以,当对象没有重写 equals 时,== 与 equals 是等价的。
另外:
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2); int[] id = new int[9];
//数组下就不能这么装了...
//int[] ints = set.toArray(new Integer[0]);
Integer[] integers = set.toArray(new Integer[0]); for(int i=0;i<=set.size()-1;i++){
id[i] = set.toArray(new Integer[0])[i];
}