什么是自动装箱和拆箱
概念:装箱就是自动将基本类型数据转为包装类型;拆箱就是自动将包装类型转为基本类型。
具体实现:
// 自动装箱:
Integer total1 = 99; // 编译后 Integer total = Integer.valueOf(99)
// 自动拆箱
int total2 = total1; // 编译后 int total2 = total1.intValue()
源码分析:
valueOf
判断i的大小是否在 [-128,127]
① 在,则从缓存池中获取Integer对象
② 不在,则new一个新对象
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的一个静态内部类)进行类加载时创建的,具体代码如下
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;
}
intValue
这个就很简单了
1 @Override
2 public int intValue() {
3 return value;
4 }
相关问题汇总
比较大小
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2); //true
System.out.println(i3==i4); //false
}
}
两个Integer对象进行大小对比, 当值在[-128,127]之间,则返回true。否则返回false
建议:在写代码时不要用 == 来比较Integer, 而是使用equals。
缓存池
整型:Integer、Short、Byte、Character、Long这几个类是有缓存池的。
浮点型:Double、Float是没有缓存池的。
Boolean: 也类似缓存池,但它内部只有两个对象。
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
装拆箱情况
① 当一个包装类型和一个基本数据类型相遇时,会将包装类型拆箱
②
1 Integer num1 = 100;
2 int num2 = 100;
3 Long num3 = 200l;
4 System.out.println(num1 + num2); //200
5 System.out.println(num3 == (num1 + num2)); //true
6 System.out.println(num3.equals(num1 + num2)); //false
这里分析第六行为什么false
equals 源码
1 @Override
2 public boolean equals(Object o) {
3 return (o instanceof Long) && (((Long) o).value == value);
4 }
可以发现,它必须满足两个条件才返回true
1、类型相同
2、内容相同
所以false是因为类型不同。
陷阱1
1 Integer integer100=null;
2 int int100=integer100;
这里会抛出空指针异常,原因是编译后代码为
1 Integer integer100=null;
2 int int100=integer100.intValue(); // 这里因为integer100为空,故抛出空指针
陷阱2
当一个基本数据类型和包装类型进行 == 、 != 比较时,会将 包装类型自动拆箱,而此时如果包装类型为null,则会抛出空指针异常。
1 Integer a = null;
2 int b = 1;
3 if (a == b) {
4 }