前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >-128 == -128 ?| Integer

-128 == -128 ?| Integer

作者头像
做棵大树
发布2022-09-27 19:56:34
发布2022-09-27 19:56:34
23600
代码可运行
举报
文章被收录于专栏:代码日志代码日志
运行总次数:0
代码可运行

-128 == -128 吗?

之前一直没有注意到 Integer 类型的判断问题,我认为 “在数值判断中,== 和 equals 的效果是相同的”,直到今天写题发现包装类下的“不能”使用 == 进行判断。

Integer 是 int 的包装类,将基本类型赋值给包装类,会进行自动装箱,自动装箱操作就是进行 valueOf(int arg1)一般 new 创建的Integer会在堆中。也正是因为是包装类,所以便不再是简单的基础数据类型。

我们都知道,对于 int 进行比较,使用 == 即可判断。但是当对 Integer 类型进行判断时候,便不再是简单的数值比较了,而是对于对象间地址的比较,当生成的值处于 -128 <= value <= 127(默认),底层会直接从其缓存IntegerCache 中取出以提高效率,在这时候 == 是可以匹配的。

Integer 内部缓存类 IntegerCache 实现源码

代码语言:javascript
代码运行次数:0
运行
复制
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() {}
    }

但是当超出这个范围进行创建时,两对象之间则又有了不同的地址,也就无法再使用 == 进行比较了。这个时候我们需要使用包装类的 equals 方法进行判断。

Integer 对于 Object 的 equals 方法进行了二次封装,对于该方法,官方给出的解释如下:

代码语言:javascript
代码运行次数:0
运行
复制
public boolean equals(Object obj)

> Compares this object to the specified object. The result is true if and only if the argument is not null and is an Integer object that contains the same int value as this object.

翻译过来就是:将此对象与指定的对象进行比较。其结果是 true 当且仅当该参数(及obj)不是 null 并且是 Integer 对象包含有相同 的int 值。

内部重写的源码是这个样子的:

代码语言:javascript
代码运行次数:0
运行
复制
public boolean equals(Object obj){
    if(obj instanceof Integer){
        return value == ((Integer)obj).intValue(); // 拆箱操作
    }
    return false;
}

其中又调用了 intValue 方法,该方法的实现是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
public int intValue()  
{  
  return value;  
}  

在使用 equals 比较的过程中,会先使用 instanceof 对传入的数据类型进行判断,如果类型不匹配,会直接返回 false,当类型相同时,则会再调用 inValue() 方法进行拆箱,转化为基本数据类型 int 后与当前对象的值 value 进行比较。

此时参与比较的会变成两个 int 类型的值,而非是 Integer 类型的对象,从而可以得到我们想要的值比较结果。

✔小结

其实简单些记忆的话,可以记作 「==比较的是地址,equals比较的是值」。BTW:对于包装类与基本类型,我们在日常使用中还是要注意他们之间涉及到的一些装箱和拆箱的操作的。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 做棵大树 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ✔小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档