a == b
和 和有a.Equals(b)
什么区别?
a == b
和 和有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
这取决于类型a
和b
。
特别是,Equals
是一个虚方法,因此它的行为不依赖于 a 和 b 的编译时类型。
在 Java 中,==
总是会按引用进行比较,这不一定是您想要的,尤其是对于字符串。
在 C# 中,==
可以重载,但不是虚拟的(它是一种static
方法)。因此,如果a
或b
被声明为object
,它将通过引用进行比较,即使它们的实际类型重载operator ==
。
此外,如果 a 是,a.Equals(b)
则会抛出NullReferenceException
(NullPointerException
在 Java 中) 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
== 是语言中的基本运算符。运算符 == 测试以查看两个对象引用变量是否引用了完全相同的对象实例。
equals() 是一个实例方法,基本上由 java.lang.Object 类定义。方法 .equals() 测试以查看相互比较的两个对象是否等效,但它们不必是同一对象的完全相同的实例。
== 运算符始终为您提供相同的结果,但 equals () 方法根据您的实现(实现的逻辑)为您提供输出。正确覆盖 equals: 每当覆盖 equals () 方法时的注意事项。
1. 自反:对于任何非空引用 x,x.equals(x) 应该返回 true。
2. 对称:对于任何非空引用 x 和 y,如果 x.equals(y) 为真,则 y.equals(x) 必须返回真。
3. 传递性:对于任何非空引用 x、y 和 z,如果 x.equals(y) 为真,y.equals(z) 为真,则 x.equals(z) 必须返回真。
4. 一致:对于任何非空引用 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,而不会更改为 equals 比较提供的信息。
5.对于任何非空引用x,x.equals(null)必须返回false。注意:如果 o1.equals(o2) 为真,则 o1.hashcode() ==o2.hashcode(),但反过来可能是也可能不是。
例子:
整数 i = 新整数(10); 整数 j = i;
在上面的代码中。i == j 为真,因为 i 和 j 指的是同一个对象。
整数 i = 新整数 (10); 整数 j = 新整数(10);
在上面的代码中, i == j 是 FALSE,因为虽然它们的值都是 10,但它们是两个不同的对象。但是 i.equals (j) 将返回 true。
使用自动装箱
整数 i = 10;
整数 j = 10;
布尔值 b = (i == j);
System.out.println(b);
这将返回 TRUE,因为范围 -127 到 128 之间的整数被合并,因此在这种情况下,两者都是相同的对象(JVM 不会创建新对象,它将从池中检索它)。
String 类覆盖了 equals 方法,所以这里有一个 equals vs. == String s1 = new String ("abc") 的例子;String s2 = new String("abc");
注意:字符串是在字符串常量池中创建的,因此当我们创建像 String s=”abc” 这样的字符串时,它将通过调用本地方法 intern () 来检查池,如果它没有找到任何字符串,则它是否存在于现有池中将创建一个新的,但如果我们调用 new 运算符,那么它将创建一个新的字符串,而不管是否检查池是否存在。
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
a == b
如果引用包含相同的值,即它们指向同一个对象,或者它们都为空,则返回 true。
equals()
可以重写该方法以比较对象。例如, on Strings
,true
如果字符串包含相同的字符串,即使它们是不同的字符串对象,该方法也会返回。你可以用你自己的对象做类似的事情。
o.equals()
如果 o 是空引用,则会抛出异常。
==
使用对象的引用,或者如果是整数/浮点数等,则比较实际数字。从技术上讲,它只是比较内存位置中的内容。虽然.equals
使用对象类内部的方法来比较对象,但可以为您的各个类覆盖它。此外,由于数组也处理引用,因此不使用array1[i] = array2[i]
、 使用arraycopy
或也很有帮助clone()
。我认为.equals
也可以与数组一起使用
假设我们有a
和b
或两个不同的对象,我们想比较这两个对象引用。然后我们使用==
运算符,当使用时a.equals(b)
,它比较字符串值。
==
检查对象引用,基本上它比较哈希码。Equals 使用对象中的内容。请记住,我们必须.equals
在我们的类中相应地覆盖该方法。
== 检查引用是否指向内存中的同一个对象
现在,
尽管对象类中的 equals 方法的代码只是检查 == 的引用,但可以覆盖它以添加您自己的相等检查。
在像 String 这样的类中,重写的方法检查字符串文字是否正确。所以基本上它可以用来检查值是否相同。
==,它只根据它们的地址返回一个哈希码的值,所以不同的地址即使字符串或任何类似的数据也返回false......这对条件有帮助,返回布尔值。
假设的类型
a
和b
是引用类型:在 Java 中, == 将始终比较标识- 即两个值是否是对同一对象的引用。这也称为引用相等。Java 没有任何用户定义的运算符重载。
在 C# 中,这取决于。除非有一个处理它的重载运算符,== 将表现得像 Java(即比较引用相等)。但是,如果存在与and的编译时类型匹配的重载(例如,如果它们都声明为字符串),则将调用该重载。这可以按照它想要的方式运行,但它通常实现值相等(即,可以引用不同但相等的值,但仍会返回 true)。
a
b
a
b
在这两种语言中,
a.Equals(b)
或a.equals(b)
将调用由声明的虚拟Equals
/equals
方法Object
,除非a
. 这可能会或可能不会在a
引用的对象的执行时类型中被覆盖。在 .NET 和 Java 中,实现Object
也检查身份。请注意,这取决于执行时类型,而不是重载解析所依赖的编译时类型。当然,如果
a
是,null
那么当你尝试调用or时你会得到一个NullReferenceException
/ 。NullPointerException
a.equals(b)
a.Equals(b)