Java中==和equals方法的分析

原文引用https://www.dazhuanlan.com/2019/08/26/5d62fa816b34b/

前言

== 和 equals是经久不衰的面试题,记得刚毕业的时候我也被问到过很多次,从最开始的一脸懵逼到最后的从容回答,本文我们就来分析下这两者之间的区别和联系。

为避免阅读疲劳,我这里先放上结论:

联系:

  • 两者都被用来进行比较操作
  • 当equals()未被重写时,两者的用途和比较的内容相同,即都是比较对象的引用地址是否相同

区别:

  • ==既可以比较基本数据类型,亦可用在对象之间。equals()只能比较对象间的关系
? 基本数据类型 对象类型
== 比较值是否相同 比较引用地址是否相同
equals - equals()未被重写时比较对象的引用地址是否相同
equals()被重写后根据equals()实现逻辑而定

下面我们对以上的结论进行验证.

两者的联系

==:关系操作符,计算两个操作数之间的关系,返回一个boolean类型的结果

equals:Object类的一个方法,用来比较两个对象之间的关系,返回一个boolean类型的结果

从Object类中的equals()实现来看他们两个都是用来进行==的逻辑比较,并且都返回一个boolean值

但是仔细分析,

  • ==的操作数是有类型区分的(基本数据类型,对象类型),所以不同的操作数会有不同的计算逻辑。
  • 而equals()是Object一个方法,既然是基类方法那么就可以被子类重写,所以实际的比较逻辑还是要根据重写内容来判断

栗子:Date类的equals()被重写,实际判断的是时间戳的值是否相等

==的使用

== 是一个关系操作符,他有两个操作数,操作数则分为两个大类:基本数据类型、引用数据类型。

直接上代码:

123456789101112131415
public class  {    public static void main(String[] args) {        int a = 10;        int b = 10;        System.out.println("a==b:"+(a==b));

String s1 = "A";        String s2 = "A";        String s3 = new String("A");//栈内存中对象引用s3指向堆内存中的A对象        String s4 = new String("A");//栈内存中对象引用s4指向堆内存中的另一个A对象        System.out.println("s1==s2:"+(s1==s2));        System.out.println("s1==s3:"+(s1==s3));        System.out.println("s3==s4:"+(s3==s4));    }}

运行结果如下:

1234
a==b:trues1==s2:trues1==s3:falses3==s4:false

具体分析下输出的结果

a==b:操作数a、b是基本数据类型,使用==直接比较ab在栈内存中的值是否相等,故结果为true

s1==s2:操作数s1、s2为对象类型,String s1 = "A"执行时,堆内存的常量池中会开辟空间存放A对象,栈内存中的引用变量s1会指向该对象的内存地址,s2创建时同样会指向常量池中的A,s1和s2指向的是同一个对象所以结果为true

s1==s3:s2是通过new()来创建对象,堆内存中会开辟空间存放对象,显然s1和s3的内存地址是不同的,s1指向常量池中的”A”,s2指向堆内存中的new String(“A”),所以结果为false

s3==s4:s3、s4是通过new()的方式创建的两个不同的对象,他们的内存地址不同,结果必然为false

总结:

==作为关系操作符,当操作数为基本数据类型时,直接判断值是否相同,
当操作数为对象类型时,判断两对象的内存地址是否相同

equals()

equals()方法时Object类的方法之一,这意味着所有Java类都继承了这一方法,并可以对他进行重写,比如String、Date、Integer…..

在上文我们通过Object类中equals()方法的源码可知,在未被重写时,equals()内部其实是调用了==进行判断。

下面我们看下String类对equals()的实现:

可见,String类的equals方法中,先判断两个对象是否内存地址相同,如果内存地址不同,则判断值是否相同
修改之前的代码测试如下:

123456789101112
public class Demo {    public static void main(String[] args) {

String s1 = "A";//栈内存中对象引用变量s1指向常量池中的A        String s2 = "A";//栈内存中对象引用s2指向常量池中的A        String s3 = new String("A");//栈内存中对象引用s3指向堆内存中的A对象        String s4 = new String("A");//栈内存中对象引用s4指向堆内存中的另一个A对象        System.out.println("s1.equals(s2):"+(s1.equals(s2)));        System.out.println("s1.equals(s3):"+(s1.equals(s3)));        System.out.println("s3.equals(s4):"+(s3.equals(s4)));    }}

运行结果如下:

123
s1.equals(s2):trues1.equals(s3):trues3.equals(s4):true

具体分析下输出的结果

s1.equals(s2):相同的内存地址直接返回true

s1.equals(s3):内存地址不同,开始判断值是否相同,值都为”A”,返回true

s3.equals(s4):内存地址不同,开始判断值是否相同,值都为”A”,返回true

通过上面的栗子,发现了一种现象:内存地址相同的对象其值必定相同,而内存地址不同的对象,其值关系不确定

总结:

原文地址:https://www.cnblogs.com/petewell/p/11410442.html

时间: 2024-11-09 21:26:58

Java中==和equals方法的分析的相关文章

【转】彻底弄懂Java中的equals()方法以及与"=="的区别

彻底弄懂Java中的equals()方法以及与"=="的区别 一.问题描述:今天在用Java实现需求的时候,发现equals()和“==”的功能傻傻分不清,导致结果产生巨大的偏差.所以,我决定花费时间把equals()和“==”的功能彻底弄懂,前事不忘后事之师嘛,分享给大家,希望对大家理解equals()和“==”的功能有所帮助. 二.分析探索解决问题的方法:1.Object 中的equals()方法: (1)通过查找API,说明如下: equalspublic boolean equ

java中‘==’和‘equals()’方法的有趣探索

这两天在看周志明的<深入理解java虚拟机>,受益颇多,根据书中的启示,对java中'=='和'equals()'方法的区别做了一些探索. 首先,为了更快地让进入状态,我们先来所几个判断题,例程如下,请判断各个System.out.println()输出的结果. <pre name="code" class="java"> public static void main(String[] args) { Integer a =1; Integ

Java中“==”与equals方法的区别

1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:String类对equals进行了重写:1)若是同一个对象,返回true: 2)若不是,则比较它们的值,值相同,返回true 重写代码: public boolean equals(Object anObject) { if (this == anObject) { return true; } if

如何重写Java中的equals方法

Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, double),boolean, char不是对象,其他的所有类型,不论是对象数组,列表等都扩展了Object类.了解学习Object中方法的设计原理和实现方式有助于更好的学习理解java语言.下面,我们首先学习一下Object中的equals方法. 判断两个对象相等时,JVM首先查找两个对象的hashCode, 如果两者hashCode不同,则返回false;如果

JAVA中复写equals方法

一般说来,所有类都应该复写Object中的equals方法.步骤大概分三步: 1) 判断两个对象地址是否一致 2)判断第二个对象是否为同一个子类实例 3)判断内容是否一致 class Person { public int age; public String name; public Person(int age, String name) { this.age = age; this.name = name; } public boolean equals(Object obj) { //第

JAVA中重写equals()方法的同时要重写hashcode()方法

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码.如下:(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true (2)当obj1.ha

小结下java中==与equals方法

1 public class EqualsTest { 2 3 public static void main(String[] args) { 4 String s1 = "abc"; 5 String s2 = "abc"; 6 String s3 = new String("abc"); 7 String s4 = new String("abc"); 8 9 /* 10 * 首先要明确:==比较的是对象引用,即内存中的

JAVA中重写equals()方法为什么要重写hashcode()方法?

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码.如下:(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true (2)当obj1.ha

java中的equals()方法

大家都知道,在Java中,对于对象的比较,如果用“==”比较的是对象的引用,而equals才是比较的对象的内容. 一般我们在设计一个类时,需要重写父类的equals方法,在重写这个方法时,需要按照以下几个规则设计: 1.自反性:对任意引用值X,x.equals(x)的返回值一定为true.2.对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;3.传递性:如果x.equals(y)=true, y.equals(z)=tr