你真的懂equals()吗?

6 篇文章 0 订阅

Java中Integer的true或者false问题是一个非常常见的问题,也就是==和equals的关系,那你真的懂什么是equals吗?你可能会想:不就是比较地址和比较值嘛,小学生都会,那你怕是对equals有什么误解。

本文参考:Java3y

你真的懂equals()吗?

之前也写过类似的博文,让我以为我已经彻底弄懂了这个问题,但是当我真正看到这道题时,我还是做错了。

可以先过一遍我之前的文章基本类型与包装类判断是否相等问题

public class Main {
    
    public static void main(String[] args) {
    	
    	Integer a = 1;
    	Integer b = 2;
    	Integer c = 3;
    	Integer d = 3;
    	Integer e = 321;
    	Integer f = 321;
    	Long g = 3L;
    	Long h = 2L;
    	System.out.println(c==d);
    	System.out.println(e==f);
    	System.out.println(c==(a+b));
    	System.out.println(c.equals(a+b));
    	System.out.println(g==(a+b));
    	System.out.println(g.equals(a+b));
    	System.out.println(g.equals(a+h));
    	
    }
}

先自己思考一下吧!!!


在解这道题之前,相信很多人都已经知道了,在Java中会有一个Integer缓存池,缓存的大小是:-128~127

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 */

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() {}
}

也就是说>127的和<-128的都会new一个新的Integer:

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

那么前四个答案显而易见了,关键是后面后面三个答案是啥???


简单解释一下这道题:

使用==的情况:

  • 如果比较Integer变量,默认比较的是地址值
  • Java的Integer维护了从-128~127的缓存池
  • 如果比较的某一边有操作表达式(例如a+b),那么比较的是具体数值

使用equals()的情况:

  • 无论是Integer还是Long中的equals()默认比较的是数值

  • Long的equals()方法,JDK的默认实现:会判断是否是Long类型

  • 注意自动拆箱,自动装箱问题。

这里需要特别注意一下Long中的equals方法,我们可以点进Long.class看看

在这里插入图片描述

显而易见,Long的equals()方法,JDK的默认实现:会判断是否是Long类型。(Float、Double的equals()方法其实也是这样判断的)

反编译一下看看:

import java.io.PrintStream;

public class Main_1 {
    public static void main(String[] paramArrayOfString) {
        Integer localInteger1 = Integer.valueOf(1);
        Integer localInteger2 = Integer.valueOf(2);
        Integer localInteger3 = Integer.valueOf(3);
        Integer localInteger4 = Integer.valueOf(3);
        Integer localInteger5 = Integer.valueOf(321);
        Integer localInteger6 = Integer.valueOf(321);
        Long localLong = Long.valueOf(3L);

        // 缓存池
        System.out.println(localInteger3 == localInteger4);

        // 超出缓存池范围
        System.out.println(localInteger5 == localInteger6);

        // 存在a+b数值表达式,比较的是数值
        System.out.println(localInteger3.intValue() == localInteger1.intValue() + localInteger2.intValue());

        // equals比较的是数值
        System.out.println(localInteger3.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue())));
        // 存在a+b数值表达式,比较的是数值
        System.out.println(localLong.longValue() == localInteger1.intValue() + localInteger2.intValue());
        // Long的equals()先判断传递进来的是不是Long类型,而a+b自动装箱的是Integer类型
        System.out.println(localLong.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue())));

        // ... 最后一句在这里漏掉了,大家应该可以推断出来
    }
}

答案:

  • true
  • false
  • true
  • true
  • true
  • false
  • true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值