在一些面试题中经常会遇到:Integer类型的值比较大小的问题,在此顺便总结一下:
code:
public static void main(String[] args) {
int i1 = 127;
Integer i2 = 127;
Integer i21 = 127;
Integer i3 = new Integer(127);
Integer i31 = new Integer(127);
int i4 = 128;
Integer i5 = 128;
Integer i51 = 128;
Integer i6 = new Integer(128);
//
System.out.println("Integer i2 = 127;");
System.out.println("Integer i21 = 127;");
System.out.println("=====》" + (i2 == i21));
System.out.println("");
System.out.println("Integer i5 = 128;");
System.out.println("Integer i51 = 128;");
System.out.println("=====》" + (i5 == i51));
System.out.println("");
System.out.println("Integer i2 = 127;");
System.out.println("Integer i3 = new Integer(127);");
System.out.println("=====》" + (i2 == i3));
System.out.println("");
System.out.println("Integer i5 = 128;");
System.out.println("Integer i6 = new Integer(128);");
System.out.println("=====》" + (i5 == i6));
System.out.println("");
//
System.out.println("int i1 = 127;");
System.out.println("Integer i2 = 127;");
System.out.println("=====》" + (i1 == i2));
System.out.println("");
System.out.println("int i1 = 127;");
System.out.println("Integer i3 = new Integer(127);");
System.out.println("=====》" + (i1 == i3));
System.out.println("");
System.out.println("int i4 = 128;");
System.out.println("Integer i5 = 128;");
System.out.println("=====》" + (i4 == i5));
System.out.println("");
System.out.println("int i4 = 128;");
System.out.println("Integer i6 = new Integer(128);");
System.out.println("=====》" + (i4 == i6));
System.out.println("");
//
System.out.println("Integer i3 = new Integer(127);");
System.out.println("Integer i31 = new Integer(127);");
System.out.println("=====》" + (i3 == i31));
System.out.println("");
}
result:
Integer i2 = 127;
Integer i21 = 127;
=====》true
Integer i5 = 128;
Integer i51 = 128;
=====》false
Integer i2 = 127;
Integer i3 = new Integer(127);
=====》false
Integer i5 = 128;
Integer i6 = new Integer(128);
=====》false
int i1 = 127;
Integer i2 = 127;
=====》true
int i1 = 127;
Integer i3 = new Integer(127);
=====》true
int i4 = 128;
Integer i5 = 128;
=====》true
int i4 = 128;
Integer i6 = new Integer(128);
=====》true
Integer i3 = new Integer(127);
Integer i31 = new Integer(127);
=====》false
根据实际输出的结果:
有关Integer对象的==比较(值相同的情况下):
首先数值类型有三种:int ;Integer x = new Integer();Integer x = val
所以一共有5种:
如果两个Integer x = new Integer():都为false
==========
如果一个是int x,一个是Integer x = val:都为true
如果一个是int x,一个是Integer x = new Integer():都为true
==========
如果两个都为Integer x = val:如果范围在-128~127为true,否则false
如果一个是一个是Integer x = val,Integer x = new Integer():都为false
总结&解释:
1、有int类型数据和integer相关属性比较时,值相同则==结果都为true
(原因:int和Integer相比时,Integer类会自动拆箱,转化为值的比较)
2、如果两个都为Integer x = val:如果范围在-128~127为true,否则false
(原因:看下面^_^)
3、如果一个是一个是Integer x = val,Integer x = new Integer():都为false
(原因:一个指向常量,一个指向堆内对象,当然不同。ps:和int比它不会去拆箱比较。)
4、如果两个Integer x = new Integer():都为false
(原因:两个new出来的对象都是在堆里面,是不同的两个对象,当然不同了)
关于第二点的解释:
java的Integer类中有这么一个特殊的存在:
/**
* 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 {@code -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) {
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() {}
}
根据作者的注释和代码可知这段代码的作用是:
加载Integer类的时候,作为静态内部类,IntegerCache被加载,会去执行静态代码块:
1、首先读取sun.misc.VM中的java.lang.Integer.IntegerCache.high配置值,没有的话,用于计算缓存数组长度的h值为127,否则进入2环节(这边我本地断点进不去,囧)。
2、用max函数和127相比,取了最大值,即i这个变量的最大值为127。
3、再拿i和Integer.MAX_VALUE - (-low) -1作比较取最小值赋值给h,用于计算缓存数组的长度。
这句为什么要这么写的呢,反着来看:
首先:java星人都知道,Integer的最大值为2的32次方,即65535,那么可以推导出:
(high - low) + 1<=65535
=>
high <= 64435-1+low
=>
high==h<=64435-1-(-low) ,bingo~~~
当然也不能太小,作者设了个127为最小值,emmm
4、cache = new Integer[(high - low) + 1],说明cache的值最小为127+128+1=256,设置个数组,初始化大小256
5、遍历数组设值,从j(-128)开始++,即形成一个数值从-128~127的缓存数组。
6、最后,IntegerCache.high >= 127,判断high的值是否大于等于127。wait...这和上面判断真的没重复吗,anyway,到这数组就完美构建完成了。
在比较的时候:
Integer i = x 在编译时,会翻译成为 Integer i = Integer.valueOf(x)
看看这个方法:
首先,确确实实看到缓存数组的值:-128~127,共256个值哦
那么如果我们的值在-128~127范围内,会从Integer.cache数组中取到对应下标的Integer对象,那就==啦,反之就会去new一个新的对象,就不相等了。