== 和 equals的区别

== 和 equals的区别

前言

​ 相信很多兄弟们在面试的过程中有被面试官问过:“==”和equals有什么区别?

​ KK最开始自己的回答是:"=="比较的地址值,equals比较的是实际的值。当然了,最后的面试结果肯定是不理想的(还是KK自己太菜了)。面试结束后,我就开始上网浏览相关的文章,现在才算是对这俩玩意有了一个相较而言清晰的认知。让我们开始吧!
在这里插入图片描述

==

​ 首先需要提一下Java基础中的数据类型。Java中包含了8中基本数据类型以及无数的引用数据类型。其中基本数据类型包括:byte、short、int、long、boolean、float、double、char

​ 先来看一段代码:

int i = 1;
int j = 1;

String x = new String("Hello Word");
String y = new String("Hello Word");

System.out.println(x == y); // false
System.out.println(i == j); // true

​ int类型的比较的结果是true(int只是举例,其他基本数据类型得到的结果和int相同),String类型的比较的结果是false。开始不是说"=="比较的不是地址值么?

​ 其实是这样的,基本数据类型中"=="比较的是数值,引用数据类型比较的是地址值

​ 上述代码中,在申明两个String类型的对象之后,两个String类型的对象引用分别指向堆内存中不同的地址值,所以比较结果是false。然而基本数据类型比较的值,所以结果为true。😀

​ 有的同志们就要问了,我平时申明一个字符串的时候从来都是这么写的,代码如下:

String x = "Hello Word";
String y = "Hello Word";

System.out.println(x == y); // true

​ 这个时候的结果为什么又是true了?String不是引用数据类型么?引用数据类型比较的不是地址值么?KK你不是搁着扯犊子呢么?在这里插入图片描述

​ 上述代码中,其实在申明第一个字符串的时候,字符串是存在JVM的常量池中的,在申明第二个字符串的时候,Jvm发现,这个“Hello Word”在我的常量池中已经存在了,直接让第二个变量引用它就好了。这时候两个String的变量引用的是一个地址值,结果当然是true了。

​ 所以“==”在比较引用数据类型的时候比较的是地址值是没有错滴。

equals

​ 首先我们知道所有类的equals方法继承于顶级父类Object,我们先来看看Object类中的equals方法

public class Object {
    ...
    public boolean equals(Object obj) {
    	return (this == obj);
	}
}

​ 看!Object中的equals方法比较的是地址值!并不是比较真实的值。所以equals方法到底比较的是什么?

​ Java中类都是继承于Object类。每个类都会将Object类中equals方法继承过来。如果一个类没有重写equals方法,那么在使用equals方法的过程中还是比较的是地址值。

​ 如果重写了!例如String类的equals方法:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

​ 上面是String自己重写的equals方法,它比较的就是值,并非地址值。

​ 我们再来看下int类型的包装类Integer的equals方法:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

​ Integer中equals方法调用了intValue()方法,比较也并非是地址值而是值

总结

​ 上面这一堆最后KK得出来的结论就是

​ 1.“==”在比较基本数据类型的时候比较的值,在比较引用数据类型的时候比较的是地址值

​ 2.equals方法,如果当前类没有重写Object类中的equals(),那么比较的就是地址值。如果重写了equals方法,实现了值的比较,那么就是比较的是值。例如String类和Integer类。

​ 如果各位兄弟们发现KK有哪些地方写的不对,欢迎批评指正与交流,收工!
在这里插入图片描述

题外话

​ 写完上面这些内容的时候,KK想到了一个比较经典的题目,也算是自己也重新回顾记录一下。

Integer i = 127;
Integer j = 127;

Integer x = 128;
Integer y = 128;

System.out.println(i == j); // true
System.out.println(x == y); // false

​ 为什么第一个比较的结果是true,第二个false?如果说“==”比较的都是地址值,那么结果要么都是true,要么都是false。为什么会有不一样的结果?

​ 让我们反编译下代码就明了了
在这里插入图片描述

​ 我们可以看到,在申明Integer变量的时候,实际上是执行了自动装箱的过程,也即是Integer.valueOf ();

​ 我们来看下valueOf的源码

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

​ 注释就不放进来了,KK简单说下大致意思,就是-128 到 127之间的数值在Integer中是有一个静态数组进行缓存的,如果传进的数值刚好 >= -128 并且 <= 127 ,会直接返回静态数组中的的Integer对象,否则就返回一个新的Integer对象。

​ 我们知道在Java中被static修饰的,在JVM中就是唯一的,所以当声明两个Integer 类型的127时,其实自动装箱的返回的结果是同一个Integer对象,所以通过“==”得到的结果是true。

​ 如果声明的Integer类型超过127或者比-128小,就会返回新的Integer对象。这样上面的代码是不是就解释的通了。

参考文章

https://www.cnblogs.com/dolphin0520/p/3592500.html

https://www.cnblogs.com/wang-yaz/p/8516151.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值