a == b
和a.Equals(b)
之间的区别是什么?
答案 0 :(得分:51)
假设a
和b
的类型是引用类型:
在Java中,==将始终比较身份 - 即两个值是否是对同一对象的引用。这也称为引用相等。 Java没有任何用户定义的运算符重载。
在C#中,它取决于。除非有一个处理它的重载运算符,否则==将表现得像Java(即比较引用相等)。但是,如果存在与a
和b
的编译时类型匹配的重载(例如,如果它们都被声明为字符串),则将调用该重载。这可以表现它想要的方式,但它通常实现值相等(即a
和b
可以引用不同但相等的值,它会仍然回归真实。)
在这两种语言中,a.Equals(b)
或a.equals(b)
将调用Equals
声明的虚拟equals
/ Object
方法,除非引入了更具体的重载按编译时类型a
。这可能会或可能不会在a
引用的对象的执行时类型中被覆盖。在.NET和Java中,Object
中的实现也会检查身份。请注意,这取决于执行时类型,而不是重载决策所依赖的编译时类型。
当然,如果a
为null
,那么当您尝试拨打NullReferenceException
或{{1}时,您将获得NullPointerException
/ a.equals(b)
}。
答案 1 :(得分:13)
== 运算符检查两个对象是否完全相同,在大多数情况下不是这样的对象。 等于方法将能够在内部比较对象
示例:
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
答案 2 :(得分:3)
这取决于a
和b
的类型。
特别是,Equals
是一个虚方法,因此它的行为不依赖于a和b的编译时类型。
在Java中,==
将始终通过引用进行比较,这不一定是您想要的,特别是对于字符串。
在C#中,==
可以重载,但不是虚拟的(它是static
方法)。因此,如果a
或b
被声明为object
,则会按参考进行比较,即使其实际类型超载operator ==
。
此外,a.Equals(b)
如果a为NullReferenceException
,则会在NullPointerException
(Java中为null
)。
答案 3 :(得分:2)
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
答案 4 :(得分:1)
a == b
返回true,即它们指向同一个对象,或者它们都为空。
可以覆盖equals()
方法来比较对象。例如,在Strings
上,如果字符串包含相同的字符串,则该方法返回true
,即使它们是不同的字符串对象。你可以用自己的对象做类似的事情。
o.equals()
将抛出异常。
答案 5 :(得分:1)
==是该语言的基本操作符。 operator ==测试两个对象引用变量是否引用对象的完全相同的实例。
equals()是一个实例方法,它基本上由java.lang.Object类定义。方法.equals()测试以查看彼此比较的两个对象是否相同,但它们不必是同一对象的完全相同的实例。
==运算符总是给你相同的结果,但是equals()方法根据你的实现(实现的逻辑)给你输出。正确覆盖equals:在重写equals()方法时的注意事项。
<强> 1。自反:对于任何非空引用x,x.equals(x)应该返回true。
<强> 2。对称:对于任何非空引用x和y,如果x.equals(y)为true,则y.equals(x)必须返回true。
第3。 Transitive:对于任何非空引用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)为真,那么o1.hashcode()== o2.hashcode(),但反之亦然。
示例:
整数i = new整数(10); 整数j = i;
在上面的代码中。 i == j为真,因为i和j都指向同一个对象。
整数i = new整数(10); 整数j = new Integer(10);
在上面的代码中,i == j为FALSE,因为尽管它们都具有值10,但它们是两个不同的对象。但是,ququals(j)将返回true。
使用自动装箱
整数i = 10;
整数j = 10;
布尔值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()来检查池,因为它存在于现有池中,如果它存在找不到任何String然后它会创建一个新的但是如果我们调用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
答案 6 :(得分:0)
==
使用对象的引用,或者如果是整数/浮点数等,则它会比较实际的数字。从技术上讲,它只是比较内存位置。
尽管.equals
使用对象类中的方法来比较对象,但可以为您的各个类重写它。
此外,当数组也处理引用时,它也有助于不使用array1[i] = array2[i]
,使用arraycopy
或clone()
。
我认为.equals
也可以用于数组
答案 7 :(得分:0)
==
检查Object引用,基本上它比较了hashcode。 Equals使用对象中的内容。请记住,我们必须在课堂上相应地覆盖.equals
方法。
答案 8 :(得分:0)
假设我们有a
和b
或两个不同的对象,我们想比较这两个对象引用。然后我们使用==
运算符,在使用a.equals(b)
时,它会比较字符串值。
答案 9 :(得分:0)
==检查引用是否指向内存中的同一对象
现在,
尽管对象类中的equals方法的代码只是检查引用的==,但可以重写它以添加自己的相等性检查。
在像String这样的类中,重写的方法检查字符串文字是否正确。所以基本上它可以用来检查值是否相同。
答案 10 :(得分:-1)
==,它只根据它们的地址返回哈希码的值,所以不同的地址即使字符串或任何相似的数据也会返回false ....这对条件有帮助,返回布尔值值。