Java 基础类型int 与 Integer
int与Integer区别
- int是基础类型, Integer为对象并且为int的包装类
- int的默认值为0, Integer为null
观察以下代码执行的结果
public static void main(String[] args) {
int a1 = 127;
Integer a2 = 127;
System.out.println(a1 == a2); // true
Integer b1 = 128;
Integer b2 = 128;
System.out.println(b1 == b2); // false
Integer c1 = 127;
Integer c2 = 127;
System.out.println(c1 == c2); // true
}
复制代码
为什么三个判断出现的结果却不一样呢?这里就会提到自动拆箱与自动装箱两个概念。
自动装箱
将基础类型转换为包装类的对象称之为自动装箱。
当编译Integer a2 = 127
该语句的时候,其实将会自动的转换为如下语句
Integer a2 = Integer.valueOf(127);
复制代码
这时我们来看看valueOf(int i)
该方法的源码做了什么事情,源码如下:
注意: 我的jdk版本为 1.7
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
复制代码
其主要的逻辑为
- 判断传进来的值是否大于等于 IntegerCache.low 并且小于等于 IntegerCache.high
- 满足该条件: 调用
IntegerCache.cache
从IntegerCache缓存的cache数组里面取值并返回。 - 不满足该条件: 创建一个Integer对象
这里涉及到了一个新的类叫IntegerCache
,该类主要是缓存了一个Integer的数组,该数组存储了 -128至127 的Integer对象
我们现在来看一看 IntegerCache
这个类的源码,该类为一个静态的内部类,源码如下
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the -XX:AutoBoxCacheMax=<size> option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
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) {
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);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
复制代码
由上源码可以知道,IntegerCache
类的静态域里面执行了创建 -128到127 的Integer对象并将其放在了cache数组中。也就是说当
Integer a2 = 127
的时候,将会调用 Integer.valueOf(127)
方法,从而返回的是一个 Integer 对象。
自动拆箱
当Integer对象遇到与int类型的数据进行运算的时候,自动将Integer对象拆箱为int类型。
执行运算的时候,会调用 Integer对象的 intValue()
方法返回出内部的value,源码如下:
/**
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
public int intValue() {
return value;
}
复制代码
示例解析
int a1 = 127;
Integer a2 = 127;
System.out.println(a1 == a2); // true
复制代码
a1为int 基础类型,a2 为Integer对象,a1 == a2
的时候,a2将会调用 intValue()
方法,此时为两个基础类型使用 ==
故比对为 true
Integer b1 = 128;
Integer b2 = 128;
System.out.println(b1 == b2); // false
复制代码
b1为Integer
对象,b2也为Integer
对象,而且128
超出了IntegerCache
所缓存的Integer
对象,因此调用valueOf
方法的时候是创建了两个不同的Integer对象,对象使用 ==
进行比对的时候是判断的内存地址,因此为 false
Integer c1 = 127;
Integer c2 = 127;
System.out.println(c1 == c2); // true
复制代码
c1为Integer
对象,c2也为Integer
对象,但127
未超出了IntegerCache
所缓存的Integer
对象,因此调用valueOf
方法的时候都是返回的IntegerCache
所缓存的Integer
对象,对象使用 ==
进行比对的时候是判断的内存地址,但因为都是IntegerCache
所缓存的Integer
对象 因此为 true