关于 Integer,你要知道的事

1 int a =  1 ;

2 Integer b =  1 ;

3 Integer c =  1 ;

4 Integer d = Integer.valueOf( 1 );

5 Integer e =  new Integer( 1 );

6 Integer f =  new Integer( 1 );

7

8 Integer g =  128 ;

9 Integer h = Integer.valueOf( 128 );

10

11 System.out.println(a == b);

12 System.out.println(b == c);

13 System.out.println(c == d); 

14 System.out.println(d == e);

15 System.out.println(e == f);

16

System.out.println(g == h);

我的答案

这道题目本身没什么难度,主要考察你是不是有好奇心,对平时的工作中经常用到的一些工具类是不是熟悉。 要想做对这道题需要知道如下 2 点:

自动拆装箱

自动拆装箱就不用多说了,int 赋值给 Integer 的时候会发生自动装箱操作,Integer 赋值给 int 的时候会发生自动拆箱操作。 在 a == b 的表达式中,b 发生了自动拆箱操作转换为了它对应的 int 值。 因此 a == b 输出为 true。 在赋值语句 Integer b = 1 出现的时候发生了自动装箱操作,这个装箱操作实际使用了 Integer 的静态工厂方法 Integer.valueOf(),然后得到一个 Integer 对象。 既然是这样,那么 b == c,显然输出 true。 d 直接使用了工厂方法来构造,很明显 c == d 会输出 true。

缓存

接下来就比较好玩了,我们使用 new 初始化出来的对象和使用工厂方法构造出来的对象相等吗? 如果看过 Integer 的源码你会知道,他俩是不相等的。 我们都知道 == 比较的是对象的地址,有些人知道 Integer 有缓存功能,误认为使用 new 初始化 Integer 对象的时候也使用了缓存。 然而并不是,只有在使用了 Integer 静态工厂方法时候才会使用 Integer 的缓存对象。 由此我们可以得出 d == e 会输出 false,e == f 也会输出 false。

g 和 h 的比较在考察 Integer 缓存的大小了,默认情况下 JVM 缓存的整数大小是 -128 – 127,这个大小我们是可以通过参数更改的,例如我们让他可以缓存 -128 – 200 的整数,可以给 JVM 设置如下参数:

1-XX:AutoBoxCacheMax=128 

如果添加了如上的参数设置,那么 g == h 会输出 true,因为他们都使用了事先初始化好的缓存对象。 假设使用了默认的 JVM 参数配置,那么会输出 false,因为他们会被构造为 2 个不同的对象。 那么 JVM 为什么设置这个缓存呢? 当然是为了性能啦,典型的以空间换时间的策略。

以上就是我对于 Integer 的理解啦,小伙伴们赶紧去学习一下,有问题可以和我讨论哦。