Java中存在8种基本数据类型:byte(8位)、short(16位)、int(32位)、long(64位)、float(32位)、double(64位)、char(16位,0x0000~0xffff)、boolean(true/false)
java中不存在无符号数字类型,即C中的unsigned int等
数据类型均有其对应的包装类,数字类型的包装类均继承自Numbers。int对应的包装类为Integer。
int默认值为0,Integer默认值为null。
要理解int和Integer之间的联系和区别,可以通过反编译及查看Integer源码来学习。
下面看几个常见例子
//case 1
int int1 = 127;
int int2 = 127;
//System.out.println(int1 == int2);//true
//case 2
Integer integer1 = new Integer(127);
Integer integer2 = new Integer(127);
//System.out.println(integer1 == integer2);//false
//case 3
Integer integer3 = 127;
Integer integer4 = 127;
//System.out.println(integer3 == integer4);//true
//case 4
Integer integer5 = 128;
Integer integer6 = 128;
//System.out.println(integer5 == integer6);//false
//case 5
int int3 = integer3;
case 1:
基本数据类型比较数值。
case 2:
new出来的占据不同的内存空间,比较地址肯定是不一样的。
case 3和case 4为什么一个相等一个不相等呢,我们用jad反编译下,如下:
int int1 = 127;
int int2 = 127;
Integer integer1 = new Integer(127);
Integer integer2 = new Integer(127);
Integer integer3 = Integer.valueOf(127);
Integer integer4 = Integer.valueOf(127);
Integer integer5 = Integer.valueOf(128);
Integer integer6 = Integer.valueOf(128);
int int3 = integer3.intValue();
可见直接将int值赋给Integer,会自动调用Integer的valueOf方法:
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;
}
}
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
查看源码可以看到,IntegerCache会生成一个-128~127的数组,当调用valueOf方法时,如果形参在这个范围内,则直接返回已经生成的Integer实例,如果超出范围,才调用new Integer()。
所以,case 3中,两个127赋值为Integer,返回的是都一个实例,所以结果相等;case 4中128超出了范围,等于两个均是new Integer(128),所以结果不相等。
这种自动将基本类型转换成对应包装器类型的行为,称为装箱。
注意:Integer、Short、Byte、Character、Long这几种的valueOf实现类似,都是生成一定范围的缓存,在范围内时直接返回实例。
浮点数型的Double、Float却不同,它们都是直接调用new来生成。因为前面几种都是整数,可以生成一个有限大小的缓存,而浮点数办不到。
case 5:
与case 3相反,将Integer型赋值为int型,通过上面的反编译可以看到会自动调用Integer的intValue方法。
与装箱相反,这种自动将包装器类型转换成基本类型的行为,称为拆箱。
前面都是相同类型的进行比较,接下来看下int与Integer相互比较会怎么样
System.out.println(int1 == integer3);//true
System.out.println((int1 + int2) == integer3);//false
System.out.println(integer3.equals(int1));//true
System.out.println(integer3.equals(int1 + int2));//false
System.out.println(integer3.equals(integer1 + integer2));//false
反编译得到:
System.out.println(int1 == integer3.intValue());
System.out.println(int1 + int2 == integer3.intValue());
System.out.println(integer3.equals(Integer.valueOf(int1)));
System.out.println(integer3.equals(Integer.valueOf(int1 + int2)));
System.out.println(integer3.equals(Integer.valueOf(integer1.intValue() + integer2.intValue())));
可以看到,Integer型与int型比较时会自动拆箱;而当有算术运算符时,如+等,也会进行拆箱。
后续想到别的再补充。。。