Java equals 和 ==的区别

Java面试系列文章

面向对象的特征



1. “==” 运算符

对于基本类型和引用类型 == 的作用效果是不同的,如下所示:

如果作用于基本数据类型的变量,则直接比较其存储的 值是否相等。

如果作用于引用类型的变量,则比较的是所指向的对象的地址是否相等。

其实==比较的不管是基本数据类型,还是引用数据类型的变量,比较的都是值,只是引用类型变量存的值是对象的地址。

代码示例:

	int x = 10;
	int y = 10;
	String str1 = new String("abc");
	String str2 = new String("abc");
	String str3 = "abc";
	String str4 = "abc";
	System.out.println(x == y); 
	System.out.println(str1 == str2); 
	System.out.println(str1.equals(str2));
	System.out.println(str3 == str4); 

执行的结果:

	true
	false
	true
	true

代码解读:因为 x 和 y 指向的是同一个引用,所以 == 也是 true,而 new String()方法则重写开辟了内存空间,所以 == 结果为 false,而 equals 比较的一直是值,所以结果都为 true


2. “equals()” 方法

首先,equals()方法不能作用于基本数据类型的变量,

另外,equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,所以说所有类中的equals()方法都继承自Object类,在没有重写equals()方法的类中,调用equals()方法其实和使用==的效果一样,也是比较的是引用类型的变量所指向的对象的地址,不过,Java提供的类中,有些类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值,比如String类。

Objectequals()方法源码:

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

Stringequals()方法源码:

	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;
	}

equals 本质上就是 ==,只不过 StringInteger 等重写了 equals 方法,把它变成了值比较。看下面的代码就明白了。

首先来看默认情况下 equals 比较一个有相同值的对象,代码如下:

	package com.tinghs.springbootaction;
	
	public class Student {
	    private int age;
	
	    public Student(int age) {
	        this.age = age;
	    }
	}
	Student student1 = new Student(23);
	Student student2 = new Student(23);
	
	System.out.println(student1.equals(student2));

执行的结果:

	false

此时equals方法调用的是基类Object类的equals()方法,也就是==比较。

equals 源码如下:

	publicbooleanequals(Object obj){
	        return (this == obj);
	}

原来 equals 本质上就是 ==,所以返回false

然后我们重写下equals()方法,只要两个学生的年龄相同,就认为是同一个学生。

	package com.tinghs.springbootaction;
	
	public class Student {
	    private int age;
	
	    public Student(int age) {
	        this.age = age;
	    }
	
	    @Override
	    public boolean equals(Object obj) {
	        Student student = (Student) obj;
	        return this.age == student.age;
	    }
	}
	Student student1 = new Student(23);
	Student student2 = new Student(23);
	
	System.out.println(student1.equals(student2)); 

执行的结果:

	true

此时再比较刚刚的两个实例,返回true。


3. 结论

== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 StringInteger 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。

  1. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
    不对,两个对象的 hashCode() 相同,equals() 不一定 true

代码示例:

	String str1 = "通话";
	String str2 = "重地";
	System. out. println(String. format("str1:%d | str2:%d",  str1. hashCode(),str2. hashCode()));
	System. out. println(str1. equals(str2));

执行的结果:

	str1:1179395 | str2:1179395
	false

代码解读:很显然“通话”和“重地”的 hashCode() 相同,然而 equals() 则为 false,因为在散列表中,hashCode() 相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

廷赫斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值