Integer类相关值比较&源码分析

本文详细探讨了Java中Integer对象在不同情况下的比较,揭示了Integer对象在-128到127之间的缓存机制。通过代码示例展示了当Integer值在缓存范围内时,对象引用比较返回true,否则返回false。同时,文章解释了Integer对象创建和缓存的过程,以及如何通过Integer.valueOf()方法利用缓存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一些面试题中经常会遇到:Integer类型的值比较大小的问题,在此顺便总结一下:

code:

public static void main(String[] args) {
        int i1 = 127;
        Integer i2 = 127;
        Integer i21 = 127;
        Integer i3 = new Integer(127);
        Integer i31 = new Integer(127);

        int i4 = 128;
        Integer i5 = 128;
        Integer i51 = 128;
        Integer i6 = new Integer(128);
        //
        System.out.println("Integer i2 = 127;");
        System.out.println("Integer i21 = 127;");
        System.out.println("=====》" + (i2 == i21));
        System.out.println("");
        System.out.println("Integer i5 = 128;");
        System.out.println("Integer i51 = 128;");
        System.out.println("=====》" + (i5 == i51));
        System.out.println("");

        System.out.println("Integer i2 = 127;");
        System.out.println("Integer i3 = new Integer(127);");
        System.out.println("=====》" + (i2 == i3));
        System.out.println("");
        System.out.println("Integer i5 = 128;");
        System.out.println("Integer i6 = new Integer(128);");
        System.out.println("=====》" + (i5 == i6));
        System.out.println("");

        //
        System.out.println("int i1 = 127;");
        System.out.println("Integer i2 = 127;");
        System.out.println("=====》" + (i1 == i2));
        System.out.println("");
        System.out.println("int i1 = 127;");
        System.out.println("Integer i3 = new Integer(127);");
        System.out.println("=====》" + (i1 == i3));
        System.out.println("");

        System.out.println("int i4 = 128;");
        System.out.println("Integer i5 = 128;");
        System.out.println("=====》" + (i4 == i5));
        System.out.println("");
        System.out.println("int i4 = 128;");
        System.out.println("Integer i6 = new Integer(128);");
        System.out.println("=====》" + (i4 == i6));
        System.out.println("");

        //
        System.out.println("Integer i3 = new Integer(127);");
        System.out.println("Integer i31 = new Integer(127);");
        System.out.println("=====》" + (i3 == i31));
        System.out.println("");
    }

result:

Integer i2 = 127;
Integer i21 = 127;
=====》true

Integer i5 = 128;
Integer i51 = 128;
=====》false

Integer i2 = 127;
Integer i3 = new Integer(127);
=====》false

Integer i5 = 128;
Integer i6 = new Integer(128);
=====》false

int i1 = 127;
Integer i2 = 127;
=====》true

int i1 = 127;
Integer i3 = new Integer(127);
=====》true

int i4 = 128;
Integer i5 = 128;
=====》true

int i4 = 128;
Integer i6 = new Integer(128);
=====》true

Integer i3 = new Integer(127);
Integer i31 = new Integer(127);
=====》false

根据实际输出的结果: 

有关Integer对象的==比较(值相同的情况下):

首先数值类型有三种:int ;Integer x = new Integer();Integer x = val

所以一共有5种:

如果两个Integer x = new Integer():都为false

==========

如果一个是int x,一个是Integer x = val:都为true

如果一个是int x,一个是Integer x = new Integer():都为true

==========

如果两个都为Integer x = val:如果范围在-128~127为true,否则false

如果一个是一个是Integer x = val,Integer x = new Integer():都为false

总结&解释:

1、有int类型数据和integer相关属性比较时,值相同则==结果都为true

(原因:int和Integer相比时,Integer类会自动拆箱,转化为值的比较)

2、如果两个都为Integer x = val:如果范围在-128~127为true,否则false

(原因:看下面^_^)

3、如果一个是一个是Integer x = val,Integer x = new Integer():都为false

(原因:一个指向常量,一个指向堆内对象,当然不同。ps:和int比它不会去拆箱比较。)

4、如果两个Integer x = new Integer():都为false

(原因:两个new出来的对象都是在堆里面,是不同的两个对象,当然不同了)

 关于第二点的解释:

java的Integer类中有这么一个特殊的存在:


    /**
     * 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=<size>} 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() {}
    }

根据作者的注释和代码可知这段代码的作用是:

加载Integer类的时候,作为静态内部类,IntegerCache被加载,会去执行静态代码块:

1、首先读取sun.misc.VM中的java.lang.Integer.IntegerCache.high配置值,没有的话,用于计算缓存数组长度的h值为127,否则进入2环节(这边我本地断点进不去,囧)。

2、用max函数和127相比,取了最大值,即i这个变量的最大值为127。

3、再拿i和Integer.MAX_VALUE - (-low) -1作比较取最小值赋值给h,用于计算缓存数组的长度。

这句为什么要这么写的呢,反着来看:

首先:java星人都知道,Integer的最大值为2的32次方,即65535,那么可以推导出:

(high - low) + 1<=65535
=>

high <= 64435-1+low

=>

high==h<=64435-1-(-low) ,bingo~~~

当然也不能太小,作者设了个127为最小值,emmm

4、cache = new Integer[(high - low) + 1],说明cache的值最小为127+128+1=256,设置个数组,初始化大小256

5、遍历数组设值,从j(-128)开始++,即形成一个数值从-128~127的缓存数组。

6、最后,IntegerCache.high >= 127,判断high的值是否大于等于127。wait...这和上面判断真的没重复吗,anyway,到这数组就完美构建完成了。

在比较的时候:

Integer i = x 在编译时,会翻译成为 Integer i = Integer.valueOf(x) 

看看这个方法:

 首先,确确实实看到缓存数组的值:-128~127,共256个值哦

那么如果我们的值在-128~127范围内,会从Integer.cache数组中取到对应下标的Integer对象,那就==啦,反之就会去new一个新的对象,就不相等了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值