Java缓存池-为什么同值的Integer之间做比较,有时true,有时false

现象描述

在Java中,a == b 表达式的结果取决于 ab 的值及其对象的创建方式。

  1. ab 的值是 366 时:

    Integer a = 366;
    Integer b = 366;
    

    由于 366 超出了 Java Integer 缓存池的范围(-128 到 127),所以 ab 是两个不同的对象。因此,a == b 的结果是 false

  2. ab 的值是 100 时:

    Integer a = 100;
    Integer b = 100;
    

    因为 100 在 Java Integer 缓存池的范围内(-128 到 127),所以 ab 是同一个对象。因此,a == b 的结果是 true

总结:

  • 对于值在 -128 到 127 范围内的整数,Java 会缓存这些 Integer 对象,== 比较返回 true
  • 对于值超出这个范围的整数,Java 不会缓存这些 Integer 对象,== 比较返回 false

为了比较 Integer 对象的值是否相等,应该使用 equals 方法:

Integer a = 366;
Integer b = 366;
boolean isEqual = a.equals(b); // 结果是 true


分析

Java 缓存池(Java Integer Cache)是 Java 对象池机制的一部分,旨在优化内存使用和提高性能。它主要用于缓存和重用常见的、小范围的整数对象。

1. 缓存池的原理

在 Java 中,Integer 类通过一个内部的缓存池来存储特定范围内的整数对象。默认情况下,这个范围是 -128 到 127。对于这个范围内的整数,当使用 Integer.valueOf(int i) 方法创建 Integer 对象时,JVM 会返回缓存池中的已有对象,而不是新建一个对象。

2. 为什么使用缓存池?

使用缓存池有几个主要原因:

  • 减少内存开销:重复使用常见的整数对象可以显著减少内存分配和垃圾回收的次数。
  • 提高性能:重用现有对象比创建新对象更快。

3. 实际例子

public class IntegerCacheExample {
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b); // 输出 true

        Integer c = 200;
        Integer d = 200;
        System.out.println(c == d); // 输出 false
    }
}

在上述代码中,ab 都是 100,这个值在缓存池的范围内,所以 ab 指向同一个对象。相等性运算符 == 比较的是对象引用,因此 a == b 返回 true。而 cd 的值是 200,这超出了默认的缓存池范围,因此 cd 是不同的对象,c == d 返回 false

4. 扩展缓存池范围

你可以通过 JVM 参数 -XX:AutoBoxCacheMax=<size> 来调整缓存池的上限。例如,将缓存池范围扩展到 -128 到 1024:

java -XX:AutoBoxCacheMax=1024 YourClass

这样,Integer 值在 -128 到 1024 范围内都将被缓存。

5. 相关的源代码

缓存池的实现可以在 Integer 类的静态代码块中找到:

public class Integer {
    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 = System.getProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                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);
            }
            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() {}
    }

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

这个静态内部类 IntegerCache 负责初始化和管理缓存池。valueOf 方法在返回 Integer 对象时会检查是否可以从缓存池中获取对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值