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 propertyint 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_VALUEh = 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;}
