Skip to content

Integer1000与100的比较

1. 先说结论:

java
    Integer a = 100;
    Integer b = 100;
    System.out.println(a==b); // true

    Integer a = 1000;
    Integer b = 1000;
    System.out.println(a==b); // false

2. 浅层原因:

Integer是int的包装类型。有人可能认为下面两种声明方式是一样的,但是实际上是错误的。
java
    Integer a = 1000;
    Integer b = 1000;

    Integet a = new Integer(1000);
    Integet b = new Integer(1000);

在JVM中的内存分布情况是这样的: Alt text

在栈中创建了两个局部变量a和b,同时在堆上new了两块内存区域,他们存放的值都是1000; 变量a的引用指向第一个1000的地址,变量b的引用指向第二个1000的地址。很显然变量a和b的引用不相等。 但是上面100比较的例子为什么是true?

3. 深层原因

其实上面代码的正确简写关系应该是:

java
Integer a = 1000;
Integer a = Integer.valueOf(1000)

在定义对象a时,Java自动调用了Integer.valueOf将数字封装成对象 Alt text

而如果数字在low和high之间的话,是直接从IntegerCache缓存中获取的数据。 在Integer内部,将-128~127之间的数字缓存起来了。也就是说,如果数字在-128~127之间,直接从缓存中获取Integer对象,如果数字超过了这个范围就是,就是new出来的新对象。

所以,100在-128~127之间,对象a和对象b的引用指向了同一个地址,判断的结果是true,1000不在这个范围内,所以,a和b指向的是两个地址,判断的结果是false。

Integer类的内部为什么要做一个缓存

TIP

因为-128~127是使用最频繁的数字,如果不做缓存,会在内存中产生大量指向相同数据的对象,有点浪费内存空间。

4.正确的判断方法

使用equals方法判断

java
Integer a = Integer.valueOf(1000);
Integer b = Integer.valueOf(1000);
System.out.println(a.equals(b));

它的底层会先调用Integer类的intValue方法获取int类型的数据,然后再通过==号进行比较。此时,比较的不是两个对象的引用是否相等,而且比较的具体的数据是否相等。 使用equals方法,可以判断两个Integer对象的值是否相等,而不是判断引用是否相等。

Released under the MIT License.