Integer类中存在的缓存

    @Test
    public void intergerCache() {
        Integer intOne = 128;
        Integer intTwo = 128;
        Integer intThree = 127;
        Integer intFour = 127;

        System.out.println(intOne==intTwo);
        System.out.println(intThree==intFour);
    }
false
true

上面的代码简洁地使用了自动装箱,但是打印结果让人疑惑。
四个Integer对象被创建出来,虽然两两之间值相同,但是它们理应是四个独立的对象,==运算符比较的是对象的地址,所以结果都应该是false才对。

而Integer源码中一个内部类的注释会直接地解释你的疑惑

    /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     * ... ... ... ...
     */
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        ... ...
        ... ...
    }

我省略了详细的注释和代码,但是剩下的内容也足以解释上面奇怪的打印结果。

如果创建的Integer对象的值在 -128 127之间(默认情况下),则会直接获得从上述代码中的static数组cache中取得一个引用,而不是再创建一个新的内容完全相同的对象。

这么做提高了java的运行时效率,如果不注意这一点可能会在某些情况下写出令人不解的bug。

当我们不使用自动装箱语法时,情况又发生了变化。

    Integer intThree = new Integer(127);
    Integer intFour = new Integer(127);

    System.out.println(intThree == intFour);
false

Integer对象被显式地创建,那么缓存机制就无法起作用。通常这样的操作是没有必要的,我们应该总是使用装箱语法,而非new出包装类。

posted @ 2018-08-09 20:43  Redotz  阅读(162)  评论(0编辑  收藏  举报