Java之== 和 equals()的区别

本文详细解析了Java中==与equals的区别,==用于比较基本数据类型的值和引用类型的地址,而equals则用于比较对象的内容。文章通过示例代码及运行结果展示了不同情况下的比较方式,并介绍了字符串常量池的概念。

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

== 和equals

简单概括就是:

==比较基本数据类型的值和引用类型对象的引用地址,equals比较对象的内容。


下面我们具体来说一下这两个:

==:

我们知道java在内存中有栈(stack)和堆(heap)之分。栈中存放基本数据类型和引用类型的变量,堆中存放对象的实际内容。当我们通过new实例化一个对象时,在内存是这样存储对象的:

Student s = new Student("jack",13);

    s持有对实际对象的引用。所以引用类型的数据通过==比较的其实对象就是在内存的地址,但是对象如果不是父子关系的话不能用==来进行比较。

    基本数据类型都是保存在栈中,所以基本数据类型的==比较的就是他们的值,没有类型的限制:
int i = 65;
float f = 65.0f;
char c = 'A';
System.out.println(i == f);
System.out.println(f == c);

    运行结果:


    可以看到这个三个对象==的结果都是true,因为他们都是基本数据类型,只要值相同,==得到的结果就会返回true。

equals():
equals()方法是Object类中的一个方法,Object提供这个方法的本意是让子类重写equals()方法( 重写equals()方法相关可以参考这篇博客),如果没有进行重写的话,则还是用父类的equals()方法,我们看下Object中的equals()方法:
public boolean equals(Object obj) {
    return (this == obj);
}

    可以看到,Object中的equals()内部还是用的==来判断。


    看一下下面的这段代码,想一下他们的输出结果是什么?
package com.ljw.StringStringBuilderStringBuffer;

/**
 * Created by liujiawei on 2018/7/3.
 */
public class TestEquals {
    public static void main(String[] args) {

        String a = "ab";
        String b = "ab";
        String c = new String("ab");
        String d = new String("ab");

        System.out.print("a==b的结果是: ");
        System.out.println(a == b);
        System.out.print("a==c的结果是: ");
        System.out.println(a == c);
        System.out.print("c==d的结果是: ");
        System.out.println(c == d);
        System.out.print("ab equals的结果是: ");
        System.out.println(a.equals(b));
        System.out.print("ac equals的结果是: ");
        System.out.println(a.equals(c));

    }
}

    运行结果:


结果和你想的一样么?

在解释上面的结果之前,要先介绍一个概念:
常量池(constant pool),在方法区中,用来保存关于类,接口,方法中的常量,包括字符串常量。

知道了常量池以后,我们用内存示意图来说明上面的几个string对象的存储,相信看完以后,对上面的结果就可以理解了:
第一步:
String a = "ab";

首先在栈中存放了变量名a,因为这是字符串常量,所以去常量中找“ab”,没有找到,创建了“ab”。

第二步:
String b = "ab";

    栈中创建变量b,去常量池中找“ab”,发现已经被创建过了,所以b直接指向它。

第三步:
String c = new String("ab");

    栈中创建c,通过String的构造方法实例化的对象,在堆中创建对象,再指向方法区中的“ab”

第四步:
String d = new String("ab");

    栈中创建d,堆中创建实例化的对象,指向方法区的“ab”。


    看完上面的图,几个==的判断相信结果一目了然,至于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;
}
    可以看到,在==判断以后,会转去判断对象具体的内容,所以abcd四个用equals()比较得到的结果都会返回true。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值