参考:https://blog.csdn.net/womenghuangliang/article/details/17377285
一、Integer类型的常量池
Integer常见定义对象的几种赋值方式:
Integer i = 11;
Integer bar = new Integer(90);
Integer bar = Integer.valueOf(90);
如上几种方式创建的Integer对象有啥区别呢?
- 当我们用 Integer i = 11 的方式创建一个Integer类时,Java调用了方法Integer.valueOf()。所以第1种方式和第3种本质上是一致的。
- new操作,会申请内存,在堆中创建一个新的对象,并赋值。此种方式和常量池没有关系。
那么valueof()方法做了什么操作呢? Integer.valueOf()方法实现如下:
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);
通过上面的代码,我们可以很清楚的看到:当我们在-128到127这个范围内调用valueof()这个函数时,实际上使用的是缓存(IntegerCache)里面的值。IntegerCache是帮助我们缓存Integer的类。缓存数值的大小是由-XX:AutoBoxCacheMax=
所以:
- 对于
Integer bar = Integer.valueOf(90);
Integer baz = Integer.valueOf(90);
本质上,引用类型bar、baz指向的都是同一对象。所以bar==baz。
- 对于
Integer bar = Integer.valueOf(128);
Integer baz = Integer.valueOf(128);
本质上,是通过new操作创建了2个对象。引用类型bar和baz分别指向这两个对象。所以,bar==baz是false。
二、如下样例有助于理解Integer的常量池
- 样例1:
Integer in1 = 11;
Integer in2 = new Integer(11);
System.out.println(in1 == in2);
System.out.println(in1);
System.out.println(in2);
System.out.println(in1 == Integer.valueOf(in2)); 等同于Integer.valueOf(11),因为valueOf()函数的入参数int类型,所以传入Integer类型的in2时,要做解封装过程,结果等效传入的是11。
打印结果是:
false
11
11
true
- 样例2:
Integer a = 3;
Integer b = new Integer(3);
int c = 3;
Integer d = 256;
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a == Integer.valueOf(3));
System.out.println(b == new Integer(3));
System.out.println(d == Integer.valueOf(256));
打印结果是:
false
true
true
false
false
问题:
System.out.println(a == c);
为什么返回是true呢?因为:
Integer属于包装类,int属于基本数据类型;
只要Integer和int类型的值进行 == 比较,就会将Integer包装类拆箱为int类型,所以当进行 i01==i02比较时,就相当于两个int类型的值进行比较。基本数据类型与基本数据类型进行比较,就是比较值的内容。
- 容易混淆的样例:
Integer b = new Integer(256);
System.out.println(b == 256);
打印结果是:
true
请注意:这里是Integer的数字比较,本质上是把Integer拆包后进行值比较。和上面两个Integer对象的==本质上是不一样的。