【2021-07-01】分析程序的运行结果,并解释为什么?

258 阅读2分钟

请移步至 【DobbyKim 的每日一题】 查看更多的题目~

问:

请分析该程序的运行结果,并解释为什么?

程序一:

public class Main {
  public static void main(String[] args) {
    int a = 1000;
    int b = 1000;
    System.out.println(a == b);
  }
}

程序二:

public class Main {
  public static void main(String[] args) {
    Integer a = 1000;
    Integer b = 1000;
    System.out.println(a == b);
  }
}

程序三:

public class Main {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 1;
        System.out.println(a == b);
    }
}

程序四:

public class Main {
    public static void main(String[] args) {
        Integer a = new Integer(1);
        Integer b = new Integer(1);
        System.out.println(a == b);
    }
}

答:

程序一输出结果为:true

程序二输出结果为:false

程序三输出结果为:true

程序四输出结果为:false

解释:

首先,程序一输出结果为 true 肯定没什么好解释的,本题考察的重点在于后面程序输出结果的分析。

Integer 是 int 的装箱类型,它修饰的是一个对象。当我们使用 Integer a = xxx; 的方式声明一个变量时,Java 实际上会调用 Integer.valueOf() 方法。

我们来看下 Integer.valueOf() 的源代码:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

JDK 文档中的说明:

* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.

也就是说,由于 -128 ~ 127 这个区间的值使用频率非常高,Java 为了减少申请内存的开销,使用了 IntegerCache 将这些对象存储在常量池中。所以,如果使用 Integer 声明的值在 -128 ~ 127 这个区间内的话,就会直接从常量池中取出并返回,于是我们看到,程序二输出的结果为 false,因为 Integer = 1000;Integer b = 1000; a 和 b 的值并不是从常量池中取出的,它们指向的是堆中两块不同的内存区域。而程序三:Integer a = 1;Integer b = 1; 中的 a 和 b 指向的都是常量池中同一块内存,所以结果返回 true。

对于程序四的输出结果,我们需要知道,当 new 一个对象时,则一定会在堆中开辟一块新的内存保存对象,所以 a 和 b 指向的是不同的内存区域,结果返回 false~