从Java内存分配来看equals和==比较

    刚开始学Java的时候,遇到equals比较和==比较有时候结果总是让人惊讶,如果是以前没有接触过编程,不明白内存分配,每次都是稀里糊涂的记住一些结果。这种是true那种是false,但具体是为什么,具体自己应该怎么去分析才能分析出程序应该有的结果,今天我们就从Java内存分配的角度来聊聊。
    先上代码:
    String str1 = new String("abc");
    String str2 = new String("abc");
    System.out.println(str1==str2);
    System.out.println(str1!=str2);

    结果false true
    ==比较str1和str2的结果是false,也就是他们是不等的。这里首我们要明白==比较的是什么,==比较的是他们在内存中的地址,也就是他们是否是同一个对象。我们来看String str1 = new String("abc");这句话做了什么事,遇到new关键字会做三件事:
    1、 开辟一块堆内存空间用于存放对象(这块空间会有一个地址)
    2、 创建一个新的对象放入开辟的内存空间
    3、 将str1引用指向这块内存空间
    我们看一下Java虚拟机运行时数据区内存划分(图片来源深入理解Java虚拟机)

   

下面是简易的内存分配

从这里可以看出str1str2指向的是两块不同的内存区域,也就是两个不同的对象,所以==比较为false。但我们想要的是并不是想知道他们是不是同一个对象,我们想知道它们的值想不想等,这时候就需要使用到equals方法。比如上面的程序System.out.println(str1.equals(str2));就会出现true,这是比较的才是它们的值。下面是String类源码中实现的equals()

public boolean equals(Object anObject) {
//比较是否是同一个对象,如果是同一个对象那一定是true
    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;
}

我们知道StringJava的类,如果是自己创建的类呢,还会是一样的效果吗。比如创建一个Value


class Value{
    int i;
}
public class TestDemo {
    public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1.equals(v2));
    }
}
      结果是false,这又是为什么呢。不知道你有没有注意到我们写的Value类中根本没有equals方法,结果却能调用,那一定是调用了父类Object中的方法,我们来看一下Objectequals方法是怎么写的。
public boolean equals(Object obj) {
    return (this == obj);
}

返回了是否==,也就是equals方法的内部实现是判断是否==,这也与我们的本意不符。怎么办呢?这时候要想比较自己定义的类的实例是否相等,就必须重写equals方法,具体怎样才算相等,就看你自己的实现了。

class Value{
    int i;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Value value = (Value) o;

        return i == value.i;
    }

    @Override
    public int hashCode() {
        return i;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1.equals(v2));
    }
}

输出结果true





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值