资讯专栏INFORMATION COLUMN

IntegerCache

yiliang / 3291人阅读

摘要:类实际上是中中的缓存类,目的是节省内存消耗,提高程序性能。而当堆内存中的对象存储非常多时,就有可能造成内存泄漏。使用频率高创建对象也就越多,堆内存中的对象也就越多,所以也就会可能发生上述中的内存溢出等问题。

面试题:问以下代码输出的结果是多少?

public class IntegerTest {

    @Test
    public void test() {
        Integer a = 127;
        Integer b = 127;
        System.out.println(String.format("运行结果:%s", a == b));
        a = 128;
        b = 128;
        System.out.println(String.format("运行结果:%s", a == b));
    }

}

如果不仔细看上面的代码,那么我想很多人都会很快的说出运行的结果。但如果仔细查看代码,却不知道上述代码中的要考察的相关知识时,我想也不一定能准确说出正确的运行结果。那么下面我们看一下上述代码的运行结果:

运行结果:true
运行结果:false

你猜对了吗?为什么上面的代码显示的结果居然是不一样的呢?下面我们详细分析一下上述代码主要考察的知识点。

上述代码主要考察的是Java中Integer包装类对象的知识。但在这里有一个很隐性的知识点,也就IntegerCache对象。也就是因为这个对象的存在才导致上述代码中运行的结果不一致的。下面我们来了解一下Java中IntegerCache对象的知识。

IntegerCache

IntegerCache类实际上是Java中Integer中的缓存类,目的是节省内存消耗,提高程序性能。因为我们知道,在Java中每创建一个对象,都会将对象存储在堆内存中。而当堆内存中的对象存储非常多时,就有可能造成内存泄漏。而在我们日常的项目开发中我们使有用Integer类型的频率非常高。使用频率高创建对象也就越多,堆内存中的对象也就越多,所以也就会可能发生上述中的内存溢出等问题。所以Java为了解决上述问题。于是设计了IntegerCache类,看名字就知道IntegerCache是个缓存类,既然是缓存类,目的就是可以将相关的数据缓存下来,这里的数据指的就是Integer类的值。也就是上述代码中的等于右边的数值。那既然IntegerCache类可以缓存数字,为什么上述代码中的结果不一样呢?这个原因就是IntegerCache类有一个缓存范围。IntegerCache类缓存的数据范围为是-128到127之间。所以上述代码中前两行代码中输出结果为true(127在IntegerCache类缓存的数据范围内,于是将127缓存起来,当程序在使用这个127数字时,因为缓存中已经有了,于是直接使用缓存中的127,所以结果为true),而后二行代码输出的结果为false(超出IntegerCache类的缓存范围,于是不能缓存,所以创建了新的对象,既然是新的对象结果显然是false)。

为了验证我们上述我说的,我们看一下IntegerCache类的底层实现。下面为源码:

 /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

看源码中的注释我们知道,我们可以通过Jvm中的AutoBoxCacheMax参数来重新设置IntegerCache类的缓存范围。并且我们知道IntegerCache类使用了Integer cache[] 数据缓存数值。

这就是上述面试题中所要考察的相关知识,实际上除IntegerCache类之外,在Java中还提供了ByteCache、ShortCache、LongCache、CharacterCache等缓存对象,其中前三个缓存对象的缓存范围都是-128 到 127。而CharacterCache缓存对象则是0到127。这就是Java中IntegerCache类相关的知识,如有考虑不周,或者输写有误的地方,欢迎留言,谢谢。

原文链接:http://jilinwula.com/article/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69473.html

相关文章

  • Java Integer的缓存策略

    摘要:整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。这种缓存策略仅在自动装箱的时候有用,使用构造器创建的对象不能被缓存。行的结果为而行则为。所以行的结果为而行为。中其他类似的缓存的缓存上限可以通过虚拟机参数修改,的缓存则没法修改。 Java5为Integer的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。上面的规则默...

    endiat 评论0 收藏0
  • Integer的缓存

    摘要:基础系列的与方法类初始化顺序线程池如何弹性伸缩的几个要点的缓存什么场景下使用阻塞队列的使用及模式中的序本文主要简述的缓存。而如果大于或小于则它所指向的对象将符合垃圾回收的条件使用,在模式下,使用参数即可将的自动缓存区间设置为。 Java基础系列 Java的hashcode与equals方法 Java类初始化顺序 ThreadPoolExecutor线程池如何弹性伸缩 HashMap的...

    jay_tian 评论0 收藏0
  • 深入理解Java的整型类型:如何实现2+2=5?

    摘要:先看下这段神奇的代码执行结果那么到底做了什么神奇的事情呢先看代码所以这个例子其实包含了中整型类型的一个知识点。最后打印出来的值,实际上是的返回值。只有当输入参数不在区间内,才执行代码,基于输入参数创建一个新的实例。 先看下这段神奇的Java代码: public static void main(String[] args) throws Exception { doSom...

    aristark 评论0 收藏0
  • 为什么Integer比较要用equals

    摘要:昨晚与一同事聊天,他正在找工作,让我问他点常见面试题,然后发现他对的实现原理不是太清楚,他错误地以为只要不超过范围的两个对象就能用进行比较,但其实并不是这样的这里先上一个例子运行结果如下下面说一下,原理实现内部有一个静态变量池存放了一个 昨晚与一同事聊天,他正在找工作,让我问他点常见面试题,然后发现他对Integer, Long, BigDecimal的实现原理不是太清楚,他错误地以为...

    vspiders 评论0 收藏0
  • Hold住面试官之Integer Cache

    摘要:还有需要注意的一点是,此类缓存行为不仅存在于对象。还存在于其他的整数类型,,,。但是能改变缓存范围的就只有了。 前言 最近跟许多朋友聊了下,在这个跳槽的黄金季节,大家都有点蠢蠢欲动,所以最近就多聊聊面试的时候需要注意的一些问题,这些问题不一定多深奥,多复杂,但是一不注意的话却容易掉坑。下面看一下面试的时候经常遇到的一段代码: public class IntegerDemo { ...

    Cheriselalala 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<