相信很多朋友在面对,对象判等时经常会犹豫是用“==”还是Equals呢?有时候发现两者得到的结果相同,但有时候有不同,

究竟在什么情况下"==" 会相等,什么情况下Equals会不相等,看完本篇相信你心里自有结论。

一 基本概念

  值相等:表示比较的两个对象的数据成员按内存位分别相等,即两个对象类型相同,并且具有相等和相同的字段

引用相等:表示两个引用指向相同对象实例,也就是同一内存地址,(由引用相等,可以推出其值相等,反之则不能)

二 不同类型"=="与Equals 判等结果

  2.1 值类型

"=="运算符:表示值是否相等

"Equals":还是表示值是否相等 ,反编译后可以看到Equals 方法还是用了"=="运算符判等

public bool Equals(int obj)
{
return (this == obj);
}

所以对于值类型 不管是用 "=="运算符还是Equals方法得到的结果都是一样的(方法或运算符没有被重载)

2.2 引用类型

2.2.1 一般引用类型的   "=="运算符:表示引用地址是否相等,

两个对象虽然值相等,但是属于不同实例,所有引用地址也不一样

            object a = new string(new char['a']);
object b = new string(new char['a']);
Console.WriteLine(a == b);//false

    2.2.2一般引用类型的 Equals方法:表示值是否相等

            object a = new string(new char['a']);
object b = new string(new char['a']);
Console.WriteLine(a.Equals(b));//true

   

  2.2.3 特殊引用类型string: “==”运算符:表示值是否相等

            string a = "123";
string b = "123"; Console.WriteLine(a==b);//true

    对于为什么string 会比较值相等,相信大家都有疑问那请看下边的代码

注意:两个stirng对象在用"=="运算符判等时会调用 op_Equality()方法,这个方法里究竟做了什么操作呢,反编译一下string类 得到如下代码

我发现op_Equality()方法里居然重写了"=="运算符 且在其中调用了Equals方法,那string类的Equals方法又进行了哪些操作呢,请看图2

跟进Equals方法后发现居然是用"=="操作符判等了,瞬间我明白了大至如下:

因为string类以“==”操作符来处理值相等,

而重写“==”操作符的方法中又调用了Equals方法,

而Equals方法最终还是用"=="操作符判等,

我去~~带我们绕了个圈,最终发现string 类的 Equals方法与"=="操作符,得到结果是一样的

            //特殊引用类型string
string a = "123";
string b = "123"; Console.WriteLine(a==b);//true
Console.WriteLine(a.Equals(b));//true

三 自定义引用类型 “==”与 Equal判等

    3.1  "=="操作符:表示引用是否相等

  因为两个实例处于托管堆中不同的块中所引用地址必然不同,返回false

    class MyClass
{
public string str = "123"; }
MyClass myClass = new MyClass();
MyClass newClass = new MyClass();
Console.WriteLine(myClass == newClass);//false

    3.2 Equals() 方法:表示相个实例是否相等

   注意:为什么会是false 明明两个对象是一样的啊???为什么??为什么???  想知道原因?请接着看

    class MyClass
{
public string str = "123"; }
MyClass myClass = new MyClass();
MyClass newClass = new MyClass();
Console.WriteLine(myClass.Equals(newClass));//false

解释:所有类默认都继承了object类,Object类本身是带有几个方法 的,Equals就是其中之一,因为MyClass没有重载基类Object中的 Equals虚方法所以调用的是Object中的Equals方法 ,那Object中的Equals方法究竟又有什么操作呢?

反编译一下就知道鸟

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public virtual bool Equals(object obj)
{
return RuntimeHelpers.Equals(this, obj);
}
RuntimeHelpers.Equals()方法官方说明:此方法判断指定的 Object 实例是否被视为相等

很明显 代码中 myClass 与 newClass 属于不同实例,所以会返回false

若要返回True则需要重载Object中的Equals方法如下

    class OverrideClass
{
public string Str = "123"; //重载Object中Equals方法
public override bool Equals(object obj)
{
OverrideClass nclass = obj as OverrideClass;
//as 如果转换失败会返回null
if (nclass == null)
{
return false;
}
//对比对象属性是否相等
if (this.Str == nclass.Str)
{
return true;
}
else
{
return false;
}
} }
OverrideClass oClass = new OverrideClass();
OverrideClass nClass = new OverrideClass(); Console.WriteLine(oClass.Equals(nClass));//true

四 总结

到这里“==”与Equals就写完了总结如下:

  值类型:“==”操作符与Equals方法本质上没有区别都将得到相同结果

引用类型:"=="操作符表示引用地址是否相等,Equals方法表示  是否相等

  自定义引用类型:"=="操作符表示引用地址是否相等,Equals方法 根据重载的情况得到不同结果

特殊引用类型string:"=="与Equals 存在相互调用,得到结果都一样

“==”和Equals区别的更多相关文章

  1. 黑马程序员——JAVA基础之 == 和equals区别

    java中 == 和equals区别: java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolea ...

  2. JAVA基础之——三大特征、接口和抽象类区别、重载和重写区别、==和equals区别、JAVA自动装箱和拆箱

    1 java三大特征 1)封装:即class,把一类实体定义成类,该类有变量和方法. 2)继承:从已有的父类中派生出子类,子类实现父类的抽象方法. 3)多态:通过父类对象可以引用不同的子类,从而实现不 ...

  3. Java中的 "==" 和 "equals" 区别

    分析 "==" 和 "equals" 区别的时候先了解一下Java的内存. Java内存 “==” 和  “equals” 区别” “==”: “==”比较的是 ...

  4. ==,=和equals()区别

    equals和=,==的区别   一. ==和equals的区别 1. ==是运算符 2. equals是String对象的方法 一般有两种类型的比较 1. 基本数据类型的比较 2. 引用对象的比较 ...

  5. hashCode() 和equals() 区别和作用(转)

    出处:https://www.jianshu.com/p/5a7f5f786b75 本章的内容主要解决下面几个问题: 1 equals() 的作用是什么? 2 equals() 与 == 的区别是什么 ...

  6. ==和equals区别

    java中的数据类型,可分为两类:  1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean    他们之间的比较,应用双等号( ...

  7. java中==和equals区别

    主要是使用String时候的区别! 一.java当中的数据类型和“==”的含义 基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,bool ...

  8. == 与 equals区别(HashCode方法)

    1:==分析 1.2:基本类型比较 判断基本类型的数值是不是相等 1.3:对象类型比较 判断两个引用是不是指向同一个对象,即内存地址是不是相等. 2:equals分析 来判断对象内容是不是相等,一般有 ...

  9. C#基础之==(双等于号)与equals()区别

    C#中Equals和= =比较 这两种方式也是大家在日常编码工作当中用的比较多的判断方式.之前在使用的时候也没太关注两者在比较不同类型的时候存在哪些区别. 今天就和大家一起深入了解一下其中区别 一.值 ...

随机推荐

  1. Java基础学习总结(30)——Java 内存溢出问题总结

    Java中OutOfMemoryError(内存溢出)的三种情况及解决办法 相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各 ...

  2. Docker学习总结(4)——Docker镜像与容器命令

    Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机).bare metal. ...

  3. SpringBoot之通过Maven将项目打包成ROOT.war-yellowcong

    在项目中,我们通过maven的插件,将项目达成war包,然后通过jenkins,自动化部署项目. 核心的maven配置文件,下面这一段pom.xml的配置文件. 将项目打包成ROOT.war < ...

  4. O(1)复杂度增加和删除和随机取

    题目: https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed 非常好的解法: https://disc ...

  5. C语言之文件操作04——输入矩阵a,b,求乘积c,并打印a,b,c到文件

    //文件与数组结合 /* ================================================================= 题目:输入矩阵a,b,求乘积c,并打印a, ...

  6. (数据结构整理)NJUPT1054

    这一篇博客以一些OJ上的题目为载体,整理一下数据结构.会陆续的更新. .. 我们都知道,数据结构的灵活应用有时能让简化一些题目的解答. 一.栈的应用 1.NJUPT OJ 1054(回文串的推断) 回 ...

  7. Swift学习笔记(二)——常量与变量

    这篇博客将会学习到Swift中的常量Constants和变量Variable.这是学习语言的基础.当中能够看到Swift每句后面基本都是没有:分号的,假设有加:分号的习惯,也能够加上. (1)常量声明 ...

  8. Hadoop入门进阶步步高(二)-文件夹介绍

    二.Hadoop文件夹结构 这里重点介绍几个文件夹bin.conf及lib文件夹. 1.$HADOOP_HOME/bin文件夹 文件名 说明 hadoop 用于运行hadoop脚本命令,被hadoop ...

  9. eclipse软件快捷键的使用

    [Ct rl+T] 搜索当前接口的实现类 1. [ALT +/]    此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ ...

  10. vs输出窗口,显示build的时间

    https://stackoverflow.com/questions/82128/displaying-build-times-in-visual-studio Tools... Options.. ...