Integer a=127,Integer b=127,a==b为true还是false?

本文详细解析Integer类的自动装箱过程,说明了127与128在常量池中的不同处理方式,以及IntegerCache静态内部类的作用和缓存策略。

True,JVM会自动维护5种基本数据类型的常量池,int常量池中初始化-128到127的范围,所以当为Integer a = 127时,在自动装箱过程中是取自常量池中的数值,而当Integer a=128时,128不在常量池范围内,所以在自动装箱过程中需new 128,所以地址不一样。


以下是Integer的静态内部类

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

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

            // Load IntegerCache.archivedCache from archive, if possible
            CDS.initializeFromArchive(IntegerCache.class);
            int size = (high - low) + 1;

            // Use the archived cache if it exists and is large enough
            if (archivedCache == null || size > archivedCache.length) {
                Integer[] c = new Integer[size];
                int j = low;
                for(int i = 0; i < c.length; i++) {
                    c[i] = new Integer(j++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

VM.getSavedProperty(“java.lang.Integer.IntegerCache.high”);表示缓存范围是可以被修改的
而Byte,Short,Long 有固定范围: -128 到 127,对于 Character, 范围是 0 到 127。


LongCache

private static class LongCache {
        private LongCache() {}

        static final Long[] cache;
        static Long[] archivedCache;

        static {
            int size = -(-128) + 127 + 1;

            // Load and use the archived cache if it exists
            CDS.initializeFromArchive(LongCache.class);
            if (archivedCache == null || archivedCache.length != size) {
                Long[] c = new Long[size];
                long value = -128;
                for(int i = 0; i < size; i++) {
                    c[i] = new Long(value++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
        }
    }

CharacterCache
private static class CharacterCache {
        private CharacterCache(){}

        static final Character[] cache;
        static Character[] archivedCache;

        static {
            int size = 127 + 1;

            // Load and use the archived cache if it exists
            CDS.initializeFromArchive(CharacterCache.class);
            if (archivedCache == null || archivedCache.length != size) {
                Character[] c = new Character[size];
                for (int i = 0; i < size; i++) {
                    c[i] = new Character((char) i);
                }
                archivedCache = c;
            }
            cache = archivedCache;
        }
    }

ShortCache
private static class ShortCache {
        private ShortCache() {}

        static final Short[] cache;
        static Short[] archivedCache;

        static {
            int size = -(-128) + 127 + 1;

            // Load and use the archived cache if it exists
            CDS.initializeFromArchive(ShortCache.class);
            if (archivedCache == null || archivedCache.length != size) {
                Short[] c = new Short[size];
                short value = -128;
                for(int i = 0; i < size; i++) {
                    c[i] = new Short(value++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
        }
    }

ByteCache
private static class ByteCache {
        private ByteCache() {}

        static final Byte[] cache;
        static Byte[] archivedCache;

        static {
            final int size = -(-128) + 127 + 1;

            // Load and use the archived cache if it exists
            CDS.initializeFromArchive(ByteCache.class);
            if (archivedCache == null || archivedCache.length != size) {
                Byte[] c = new Byte[size];
                byte value = (byte)-128;
                for(int i = 0; i < size; i++) {
                    c[i] = new Byte(value++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
        }
    }
<think> 我们参考上述引用内容,特别是引用[1]、[2]、[3]、[4]、[5]关于Integer比较的内容。 根据引用[4]:Integer内部维护了一个IntegerCache,它缓存了-128到127之间的整数。当使用自动装箱(例如Integer a=100)时,实际上调用的是Integer.valueOf(int i)方法。这个方法会检查i是否在-128到127的范围内,如果在,则返回缓存中的对象;否则,创建一个新的Integer对象。 引用[5]也说明了同样的机制:valueOf方法会从缓存中取对象(如果在-128到127之间),否则新建对象。 问题中:Integer a=100; Integer b=10; 由于100和10都在-128到127的范围内,因此a和b都是从缓存中获取的Integer对象。 但是,注意:a和b的值不同,所以它们指向的是缓存中两个不同的对象(100对应的对象和10对应的对象)。 因此,当我们使用`a == b`进行比较时,比较的是两个对象的引用(内存地址)。由于a和b分别指向不同的对象(即使都是缓存对象,但地址不同),所以`a == b`的结果false。 另外,引用[2]中提到:-128~127范围内可以用==比较(注意这里指的是相同数值比较,因为同一个数值在缓存范围内会返回同一个对象,所以==会为true),而不同数值则必然为false。但如果超出范围,即使是相同的数值,用==比较也会是false(因为会创建新的对象,而两个新对象地址不同)。 所以,本题中: a=100, b=10,两个不同的值,所以不管是否在缓存范围内,它们都是不同的对象,因此`a == b`为false。 结论:`a == b`的结果false。 原理:Integer a=100和Integer b=10都是通过自动装箱调用了Integer.valueOf()方法,由于100和10都在缓存范围内,所以a和b分别指向缓存中100和10对应的Integer对象。这两个对象在内存中的地址不同,因此使用==比较(比较引用地址)结果false。 注意:如果两个Integer对象的值相同且在缓存范围内,那么用==比较结果true(因为指向同一个缓存对象);如果值相同但不在缓存范围内,则==比较结果false(因为每次都会创建新对象)。而本题中两个值不同,所以无论是否在缓存范围内,==比较都是false。 因此,对于Integer对象的比较,我们通常使用equals()方法,因为equals方法比较的是整数值(Integer重写了equals方法,比较的是包含的基本整数值)。 所以,回答用户: 在Java中,`Integer a = 100; Integer b = 10;` 然后使用 `a == b` 比较,结果false。因为a和b分别指向不同的Integer对象(即使它们都是从缓存中获取的,但100和10对应的缓存对象是不同的对象),而==比较的是对象的引用地址。 同时,我们可以生成相关问题。 </think>在Java中,`Integer a = 100; Integer b = 10;` 执行 `a == b` 的比较结果为 **`false`**。以下是详细原理分析: ### 原理分析 1. **自动装箱机制** `Integer a = 100` 和 `Integer b = 10` 触发了Java的**自动装箱**(Autoboxing),底层实际调用 `Integer.valueOf(int)` 方法: ```java Integer a = Integer.valueOf(100); // 等价于 Integer a = 100 Integer b = Integer.valueOf(10); // 等价于 Integer b = 10 ``` 2. **Integer缓存池(IntegerCache)** Java为`Integer`类设计了缓存优化(享元模式): - 默认缓存范围为 **`-128 到 127`**(可通过JVM参数调整上限[^4][^5])。 - 当`Integer.valueOf()`的参数值在缓存范围内时,直接返回缓存中的**同一个对象**;超出范围则创建**新对象**。 3. **比较逻辑** - `a == b` 比较的是对象的**内存地址**(引用地址),而非数值大小[^1][^2]。 - 由于 `100` 和 `10` **均在缓存范围内**(-128~127),但它们是**不同的数值**: - `a` 指向缓存中数值 `100` 的对象地址 - `b` 指向缓存中数值 `10` 的对象地址 - 两者地址不同 → `a == b` 返回 `false`[^3][^4]。 ### 验证示例 ```java Integer a = 100; Integer b = 10; System.out.println(a == b); // false(地址不同) System.out.println(a.equals(b)); // false(数值不同,但equals比较数值) ``` ### 正确比较方法 1. **比较数值**:使用 `equals()` 方法 ```java a.equals(b); // 比较整数值(推荐) ``` 2. **强制拆箱**:使用 `intValue()` ```java a.intValue() == b.intValue(); // 转为基本类型比较 ``` ### 关键总结 | 场景 | `==` 结果 | 原因 | |-------------------------------|-----------|--------------------------| | `Integer a=100; Integer b=100;` | `true` | 同值同缓存对象(地址相同)| | `Integer a=100; Integer b=10;` | `false` | 不同值 → 地址不同 | | `Integer c=200; Integer d=200;` | `false` | 超出缓存范围 → 新对象 | > 📌 始终用 `equals()` 比较包装类对象可避免此类问题[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值