Equals / equals和==运算符之间的区别?

a == ba.Equals(b)什么a.Equals(b)

假设ab的类型是参考类型:

  • 在Java中,==总是会比较身份 – 即两个值是否是对同一对象的引用。 这也被称为参考平等 。 Java没有任何用户定义的运算符重载。

  • 在C#中,这取决于。 除非有一个重载操作符来处理它,==将表现得像Java一样(比较引用的相等性)。 但是,如果存在与ab编译时类型相匹配的重载(例如,如果它们都被声明为字符串),那么将调用该重载。 这可以表现得如何,但它通常实现价值平等 (即ab可以指不同但相同的价值,它仍然会返回true)。

在这两种语言中, a.Equals(b)a.equals(b)将调用Object声明的虚拟Equals / equals方法,除非编译时类型a引入了更具体的重载。 这可能会或可能不会在引用的对象的执行时间类型中被重写。 在.NET和Java中, Object的实现也检查身份。 请注意,这取决于执行时间类型,而不是重载分辨率依赖的编译时类型

当然,如果anull那么当您尝试调用a.equals(b)a.Equals(b)时,将会得到一个NullReferenceException / NullPointerException a.Equals(b)

==运算符检查两个对象是否是完全相同的对象,这在大多数情况下是不可行的。 Equals方法将能够在内部比较两个对象

例:

 class Mycar { string color; Mycar(string str) { color = str; } } Mycar a = new Mycar("blue"); Mycar b = new Mycar("blue"); a==b // Returns false a.Equals(b) // Returns true 

这取决于ab的类型。

尤其是, Equals是一个虚拟的方法,所以它的行为不依赖于a和b的编译时类型。

在Java中, ==总会按引用进行比较,这不一定是你想要的,特别是对于字符串。

在C#中, ==可以重载,但不是虚拟的(这是一个static方法)。 因此,如果将ab声明为object ,即使它们的实际类型重载operator == ,它也将通过引用进行比较。

此外, a.Equals(b)将抛出一个NullReferenceException (Java中的NullPointerException ),如果a为null

 String a = "toto".Substring(0, 4); String b = "toto"; Object aAsObj = a; Assert.IsTrue(a.Equals(b)); Assert.IsTrue(a == b); Assert.IsFalse(aAsObj == b); Assert.IsTrue(aAsObj.Equals(b)); 

这个测试在.NET中传递,诀窍是Equals是一个方法,而==是一个static方法,所以aAsObj == b使用

 static bool Object.operator==(object a, object b) //Reference comparison 

a == b使用

 static bool String.operator==(string a, string b) //String comparison 

但是a.Equals(b)aAsObj.Equals(b)总是使用:

 bool String.Equals(Object obj) //String comparison 

如果引用包含相同的值,则a == b返回true,即它们指向相同的对象,或者它们都是null。

可以重写equals()方法来比较对象。 例如,在Strings ,如果字符串包含相同的字符串,则该方法返回true ,即使它们是不同的字符串对象。 你可以用你自己的东西做类似的事情。

如果o是空引用, o.equals()将会抛出一个异常。

==是该语言的基本操作符。 运算符==测试以查看两个对象引用变量是否引用完全相同的对象实例。

equals()是一个基本上由java.lang.Object类定义的实例方法。 方法.equals()测试是否两个对象相互比较是相同的,但是它们不需要是同一个对象的完全相同的实例。

==运算符总是给你相同的结果,但是equals()方法根据你的实现(实现的逻辑)为你提供输出。当重写equals()方法时,重写equals:“Considerations”。

1.自反:对于任何非空引用x,x.equals(x)应该返回true。

2.对称:对于任何非空引用x和y,如果x.equals(y)为true,则y.equals(x)必须返回true。

3.传递:对于任何非空引用x,y和z,如果x.equals(y)为true,则y.equals(z)为true,则x.equals(z)必须返回true。

4.一致性:对于任何非空引用x和y,x.equals(y)的多个调用始终返回true或始终返回false,而不更改为equals比较提供的信息。

5.对于任何非空引用x,x.equals(null)必须返回false。 注意:如果o1.equals(o2)为true,那么o1.hashcode()== o2.hashcode(),但是反过来可能是也可能不是真的。

例子:

整数i =新的整数(10); 整数j = i;

在上面的代码中。 我== j是真的,因为我和j指的是同一个对象。

整数i =新的整数(10); 整数j =新的整数(10);

在上面的代码中,i == j是FALSE,因为虽然它们都有值10,但它们是两个不同的对象。 但是,(j)将返回true。

使用自动装箱

整数i = 10;
整数j = 10;
Boolean b =(i == j);
System.out.println(b);

这将返回TRUE,因为整数范围-127到128之间的整数,所以在这种情况下,这两个是相同的对象(JVM不会创建一个新的对象,它会从池中检索它)。

String类重写equals方法,所以这里是equals和==的一个例子。String s1 = new String(“abc”); String s2 = new String(“abc”);

注意:字符串是在String常量池中创建的,所以当我们创建像String s =“abc”时,它将通过调用本地方法intern()来检查池,如果它没有找到任何字符串,会创建一个新的,但如果我们调用new操作符,那么它将创建一个新的String,而不管检查存在池。

  public class StringEqualityTest { public static void main(String []a){ String s1=new String("abc"); String s2=new String("abc"); System.out.print("s1.equals(s2) :"+s1.equals(s2)+" s1==s2 :"); System.out.println(s1==s2); String s3="abc"; String s4="abc"; System.out.print("s3.equals(s4) :"+s1.equals(s2)+" s3==s4 :"); System.out.println(s3==s4); } } 

输出:s1.equals(s2):true s1 == s2:false s3.equals(s4):true s3 == s4:true

==使用一个对象的引用,或者如果一个整数/浮点数等,那么它比较实际的数字。 从技术上讲,它只是比较内存位置。 而.equals使用对象类中的一个方法来比较对象,它可以覆盖你的个人类。 另外,由于数组也处理引用,所以不使用array1[i] = array2[i] ,使用arraycopyclone() 。 我认为.equals也可以用于数组

假设我们有a和两个不同的对象,我们想比较这两个对象的引用。 然后我们使用==运算符,当使用a.equals(b) ,它比较字符串值。

==检查Object引用,基本上它比较了这个hashcode。 Equals使用对象中的内容。 请记住,我们必须在我们的类中相应地覆盖.equals方法。

==检查引用是否指向内存中的同一个对象

现在,

尽管对象类中的equals方法的代码不过是检查引用的==,但是可以重载添加自己的相等性检查。

在像String这样的类中,重写的方法检查字符串是否正确。 所以基本上它可以用来检查值是否相同。

==,它只是根据它们的地址返回一个哈希码的值,所以不同的地址,即使字符串或任何类似的数据也返回false ….这有助于满足条件,返回布尔值。