前言
今天在学习的时候发现了一个问题,请先看一下下面的代码片段会输出什么。
Integer i1 = 200;
Integer i2 = 200;
System. out.println( i1 == i2);
源码分析
1、我们先看一下 Integer i1 = 1024; 这行代码中Integer是怎么给i1赋值的,也就是说看调用了什么方法。
首先在 Integer i1 = 1024; 打上断点,debug运行程序走到这一步再在Integer类中可能会调用的方法打个断点,按F8看会进入哪个断点。我们调试发现是调用了下面这个方法。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
也就是说 Integer i1 = 1024; 等价于 Integer i1 = Integer.valueOf(1024);
OK,下面我们来分析一下 public static Integer valueOf(int i) 方法:
IntegerCache是Integer类中的一个私有的静态内部类,代码如下:
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 之间的Integer数字全都存放到
static final Integer cache[]; 数组里面了。
我们再回到 valueOf()方法中,我们可以看到 如果 -128 <= i <= 127 就会从cache数组里面取值返回,如果不在这个范围内就会 new Integer(i); 返回。
题目分析
1、根据上面了解的知识,来思考前言中的题目。
首先我们需要知道的知识点是:
1)基本数据类型int使用 == 比较的是它们的值。
2)Integer是引用数据类型,使用 == 比较的是内存地址是否相同。
上面的题目代码可以变为:
Integer i1 = Integer.valueOf(200); //等价于 Integer i1 = new Integer(200);
Integer i2 = new Integer(200);
System. out.println( i1 == i2);
输出结果为: false
原因: i1和i2的内存地址不相同 。
2、拓展
Integer i1 = 20;
Integer i2 = 20;
System. out.println( i1 == i2);
输出结果为:true
原因:20 在区间 [-128,127 ] ,值都是从 cache缓存中取到的,所以 i1和i2的内存地址相同。
思考下面a1,a2,a3,a4 之间是否相等
int a1 = 199;
Integer a2 = 199;
Integer a3 = Integer.valueOf(199);
Integer a4 = new Integer(199);
如果把199改成99,a1,a2,a3,a4 之间又是否相等呢?